-
Notifications
You must be signed in to change notification settings - Fork 2
Description
As a developer I need to modify the learning path app to provide a full authenticated experience in the app that can provide enough code to get replication working. Until this work is completed, the app can't be fully worked on.
The following tasks must be completed as part of this work and PR:
- The code should be modified in the following repository: https://github.com/couchbase-examples/ionic-cblite-learning-path
The workflow of this business logic should be the following:
-
A user is presented with a page to authenticate with a username and password
-
The page should have a logo (Couchbase logo), a username, password, and button to authenticate the user. The UI should match the UI that is provide in the Kotlin Learning Path for Android: https://developer.couchbase.com/android-kotlin-learning-key-value?learningPath=learn/android-kotlin-sync
-
If a user clicks on the logo it should auto enter in the text for the username and password for the default user which is:
- username: [email protected]
- password: P@ssw0rd12
- When the Login button is clicked, the page should call a function. That function should use the state stored for the username and password and call a new hook named useAuthenticateUser. The hook should define a const loginHandler that return two values:
-
a error message of string value with an error message if the user was not able to authenticate OR you aren't able to pull a userProfile for the given user from the database
-
the loginHandler
-
The handler will will call an authenticate function that will defined in a future step, pull a userProfile from the database, and save it using a provider/context.
-
A UserProfile interface should be created for storing userProfiles based on a example userProfile objected provided here:
{
"docId": "user::[email protected]",
"surname": "Yen",
"givenName": "Steve",
"jobTitle": "Founder",
"department": "Engineering",
"teams": [
"AZ",
"CA",
"HI",
"NV",
"AR",
"LA",
"NM",
"OK",
"TX",
"AL",
"FL",
"MS",
"CT",
"MA",
"ME",
"NH",
"NJ",
"NY",
"RI",
"VT",
"IA",
"IL",
"IN",
"MN",
"WI",
"GA",
"NC",
"SC"
],
"email": "[email protected]"
}
-
A simple authentication function can be created in a file called authenticationService that authenticates if a username and password are correct. These values should be passed in as strings to the authentication function and it should return a boolean based on if the username and password are correct.
-
The useAuthenticateUser hook should use this authenticate function to validate if the username/password are correct. If they are incorrect the state of the error message should be set to "Error: Invalid username or password".
-
A new service should be created called UserProfileService.ts.
- This service has a constructor that takes in a DatabaseService object and stores it locally as a private variable
- The service should have a function called getUserProfile that takes in a username (email address) and returns a UserProfile interface object or undefined if it can't find the user from the inventory database.
- The userProfile documents are stored in "rbac" scope and "userProfiles" collection.
- The documentId for the userProfile is stored in the database as the format of user::username or i.e. "user::[email protected]". You will have to take the username and format a string in this format to call the collection.document function and pass it in that format for retrieving the proper User Profile object.
-
The hook should be modified so if the username and password are correct it calls the UserProfileService and get's a UserProfile object back. If the object comes back as undefined the error message state should change to "Error: Could not locate userProfile in database".
-
A provider/context react should be created that stores the userProfile that is named "UserProfileProvider" and "UserProfileContext". The provider should expose a userProfile, login, and logout functionality. the login will set the userProfile interface into state, the logout will set the userProfile state to null. The information state should be saved with useMemo.
-
The login page should be updated to show the error message provided in the useAuthenticateUser hook and display the error message if it is set. This should be exposed via the standard React API for exposing hook values.
-
The login page function that handles the button submit should call the loginHandler that is exposed username/password. After calling the function it should check the userProfile to see if it's set and if so, it should route to the main page of the application, the project listing page.
-
The menu option for logout should be modified to call code that will use the useAuthenticateUser hook and the exposed logout to log the user out, which should set the userProfile to null and then it should close the database, set the database referenced to null in the database service, and route the user back to the login page.
sudo code of the custom hook is provided below:
import { useState } from 'react';
import { authenticate } from './authService';
import { useAuthentication } from './AuthContext';
import { userProfileService} from './UserProfileService';
export const useAuthenticateUser = () => {
const [error, setError] = useState(null);
const { login } = useAuthentication();
const loginHandler = (username, password) => {
if (authenticate(username, password)) {
//get user profile from service and set it
const userProfile = userProfileService.getUserProfile(username);
if (userProfile !== undefined || userProfile !== null) {
login(userProfile);
setError(null);
} else {
setError("Error: could not locate user in the database");
} else {
setError('Error: nvalid username or password');
}
};
return { loginHandler, error };
};A PR should be submitted with this code only along with a screenshot showing the login page rendering properly.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status