Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

W25/tony/deprecate o auth #58

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 5 additions & 14 deletions backend/typescript/rest/authRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ const cookieOptions: CookieOptions = {
/* Returns access token and user info in response body and sets refreshToken as an httpOnly cookie */
authRouter.post("/login", loginRequestValidator, async (req, res) => {
try {
const authDTO = req.body.idToken
? // OAuth
await authService.generateTokenOAuth(req.body.idToken)
: await authService.generateToken(req.body.email, req.body.password);
const authDTO = req.body.idToken;
await authService.generateToken(req.body.email, req.body.password);

const { refreshToken, ...rest } = authDTO;

Expand All @@ -57,16 +55,9 @@ authRouter.post(
async (req, res) => {
try {
if (isAuthorizedByEmail(req.body.email)) {
const user = await userService.getUserByEmail(req.body.email);
const userDTO = await userService.getUserByEmail(req.body.email);
const rest = { ...{ accessToken: req.body.accessToken }, ...userDTO };

const activatedUser = user;
activatedUser.status = UserStatus.ACTIVE;
await userService.updateUserById(user.id, activatedUser);

const rest = {
...{ accessToken: req.body.accessToken },
...activatedUser,
};
res
.cookie("refreshToken", req.body.refreshToken, cookieOptions)
.status(200)
Expand Down Expand Up @@ -146,7 +137,7 @@ authRouter.post(
} else {
res.status(400).json(responseSuccess);
}
} catch (error) {
} catch (error: unknown) {
res.status(500).json({ error: getErrorMessage(error) });
}
},
Expand Down
34 changes: 0 additions & 34 deletions backend/typescript/services/implementations/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,40 +38,6 @@
}
}

/* eslint-disable class-methods-use-this */
async generateTokenOAuth(idToken: string): Promise<AuthDTO> {
try {
const googleUser = await FirebaseRestClient.signInWithGoogleOAuth(
idToken,
);
// googleUser.idToken refers to the Firebase Auth access token for the user
const token = {
accessToken: googleUser.idToken,
refreshToken: googleUser.refreshToken,
};
// If user already has a login with this email, just return the token
try {
// Note: an error message will be logged from UserService if this lookup fails.
// You may want to silence the logger for this special OAuth user lookup case
const user = await this.userService.getUserByEmail(googleUser.email);
return { ...token, ...user };
/* eslint-disable-next-line no-empty */
} catch (error) {}

const user = await this.userService.createUser({
firstName: googleUser.firstName,
lastName: googleUser.lastName,
email: googleUser.email,
role: Role.STAFF,
});

return { ...token, ...user };
} catch (error) {
Logger.error(`Failed to generate token for user with OAuth ID token`);
throw error;
}
}

async revokeTokens(userId: string): Promise<void> {
try {
const authId = await this.userService.getAuthIdById(userId);
Expand Down Expand Up @@ -298,7 +264,7 @@
password: newPassword,
});
return { success: true } as ResponseSuccessDTO;
} catch (error: any) {

Check warning on line 267 in backend/typescript/services/implementations/authService.ts

View workflow job for this annotation

GitHub Actions / run-lint

Unexpected any. Specify a different type
Logger.error(`Failed to update password. Error: ${error}`);
if (error.code === "auth/invalid-password") {
errorMessage =
Expand Down
9 changes: 0 additions & 9 deletions backend/typescript/services/interfaces/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@ interface IAuthService {
*/
generateToken(email: string, password: string): Promise<AuthDTO>;

/**
* Generate a short-lived JWT access token and a long-lived refresh token
* when supplied OAuth ID token
* @param idToken user's ID token
* @returns AuthDTO object containing the access token, refresh token, and user info
* @throws Error if token generation fails
*/
generateTokenOAuth(idToken: string): Promise<AuthDTO>;

/**
* Revoke all refresh tokens of a user
* @param userId userId of user whose refresh tokens are to be revoked
Expand Down
62 changes: 0 additions & 62 deletions backend/typescript/utilities/firebaseRestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ const FIREBASE_SIGN_IN_URL =
"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword";
const FIREBASE_REFRESH_TOKEN_URL =
"https://securetoken.googleapis.com/v1/token";
const FIREBASE_OAUTH_SIGN_IN_URL =
"https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp";

type PasswordSignInResponse = {
idToken: string;
Expand All @@ -21,27 +19,6 @@ type PasswordSignInResponse = {
registered: boolean;
};

type OAuthSignInResponse = {
federatedId: string;
providerId: string;
localId: string;
emailVerified: boolean;
email: string;
oauthIdToken: string;
oauthAccessToken: string;
oauthTokenSecret: string;
rawUserInfo: string;
firstName: string;
lastName: string;
fullName: string;
displayName: string;
photoUrl: string;
idToken: string;
refreshToken: string;
expiresIn: string;
needConfirmation: boolean;
};

type RefreshTokenResponse = {
expires_in: string;
token_type: string;
Expand Down Expand Up @@ -103,45 +80,6 @@ const FirebaseRestClient = {
};
},

// Docs: https://firebase.google.com/docs/reference/rest/auth/#section-sign-in-with-oauth-credential
signInWithGoogleOAuth: async (
idToken: string,
): Promise<OAuthSignInResponse> => {
const response: Response = await fetch(
`${FIREBASE_OAUTH_SIGN_IN_URL}?key=${process.env.FIREBASE_WEB_API_KEY}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
postBody: `id_token=${idToken}&providerId=google.com`,
requestUri: process.env.FIREBASE_REQUEST_URI,
returnIdpCredential: true,
returnSecureToken: true,
}),
},
);

const responseJson:
| OAuthSignInResponse
| RequestError = await response.json();

if (!response.ok) {
const errorMessage = [
"Failed to sign-in via Firebase REST API with OAuth, status code =",
`${response.status},`,
"error message =",
(responseJson as RequestError).error.message,
];
Logger.error(errorMessage.join(" "));

throw new Error("Failed to sign-in via Firebase REST API");
}

return responseJson as OAuthSignInResponse;
},

// Docs: https://firebase.google.com/docs/reference/rest/auth/#section-refresh-token
refreshToken: async (refreshToken: string): Promise<Token> => {
const response: Response = await fetch(
Expand Down
1 change: 0 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"react": "^18.2.0",
"react-bootstrap": "^1.5.2",
"react-dom": "^18.2.0",
"react-google-login": "^5.2.2",
"react-icons": "^3.10.0",
"react-json-schema": "^1.2.2",
"react-jsonschema-form": "^1.8.1",
Expand Down
15 changes: 0 additions & 15 deletions frontend/src/APIClients/AuthAPIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
error.code === "auth/invalid-action-code" ||
error.code === "auth/expired-action-code"
) {
console.log(

Check warning on line 50 in frontend/src/APIClients/AuthAPIClient.ts

View workflow job for this annotation

GitHub Actions / run-lint

Unexpected console statement
`Attempt to use invalidated sign-in link, ask administrator for new link: ${error.message}`,
); // link has already been used once or has expired
}
Expand All @@ -57,20 +57,6 @@
}
};

const loginWithGoogle = async (idToken: string): Promise<AuthenticatedUser> => {
try {
const { data } = await baseAPIClient.post(
"/auth/login",
{ idToken },
{ withCredentials: true },
);
localStorage.setItem(AUTHENTICATED_USER_KEY, JSON.stringify(data));
return data;
} catch (error) {
return null;
}
};

const logout = async (userId: number | undefined): Promise<boolean> => {
const bearerToken = `Bearer ${getLocalStorageObjProperty(
AUTHENTICATED_USER_KEY,
Expand Down Expand Up @@ -177,7 +163,6 @@
login,
loginWithSignInLink,
logout,
loginWithGoogle,
register,
resetPassword,
refresh,
Expand Down
Loading