Skip to content

Commit 1cfcdbf

Browse files
committed
shoo shoo oauth
1 parent 271bf86 commit 1cfcdbf

File tree

8 files changed

+27431
-2209
lines changed

8 files changed

+27431
-2209
lines changed

backend/typescript/rest/authRoutes.ts

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,16 @@ const cookieOptions: CookieOptions = {
3434
/* Returns access token and user info in response body and sets refreshToken as an httpOnly cookie */
3535
authRouter.post("/login", loginRequestValidator, async (req, res) => {
3636
try {
37-
const authDTO = req.body.idToken
38-
? // OAuth
39-
await authService.generateTokenOAuth(req.body.idToken)
40-
: await authService.generateToken(req.body.email, req.body.password);
37+
const authDTO = req.body.idToken;
38+
await authService.generateToken(req.body.email, req.body.password);
4139

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

4442
res
4543
.cookie("refreshToken", refreshToken, cookieOptions)
4644
.status(200)
4745
.json(rest);
48-
} catch (error: unknown) {
46+
} catch (error) {
4947
res.status(500).json({ error: getErrorMessage(error) });
5048
}
5149
});
@@ -57,29 +55,22 @@ authRouter.post(
5755
async (req, res) => {
5856
try {
5957
if (isAuthorizedByEmail(req.body.email)) {
60-
const user = await userService.getUserByEmail(req.body.email);
58+
const userDTO = await userService.getUserByEmail(req.body.email);
59+
const rest = { ...{ accessToken: req.body.accessToken }, ...userDTO };
6160

62-
const activatedUser = user;
63-
activatedUser.status = UserStatus.ACTIVE;
64-
await userService.updateUserById(user.id, activatedUser);
65-
66-
const rest = {
67-
...{ accessToken: req.body.accessToken },
68-
...activatedUser,
69-
};
7061
res
7162
.cookie("refreshToken", req.body.refreshToken, cookieOptions)
7263
.status(200)
7364
.json(rest);
7465
}
75-
} catch (error: unknown) {
66+
} catch (error) {
7667
if (error instanceof NotFoundError) {
7768
res.status(404).send(getErrorMessage(error));
7869
} else {
7970
res.status(500).json({ error: getErrorMessage(error) });
8071
}
8172
}
82-
},
73+
}
8374
);
8475

8576
/* Returns access token in response body and sets refreshToken as an httpOnly cookie */
@@ -91,7 +82,7 @@ authRouter.post("/refresh", async (req, res) => {
9182
.cookie("refreshToken", token.refreshToken, cookieOptions)
9283
.status(200)
9384
.json({ accessToken: token.accessToken });
94-
} catch (error: unknown) {
85+
} catch (error) {
9586
res.status(500).json({ error: getErrorMessage(error) });
9687
}
9788
});
@@ -104,10 +95,10 @@ authRouter.post(
10495
try {
10596
await authService.revokeTokens(req.params.userId);
10697
res.status(204).send();
107-
} catch (error: unknown) {
98+
} catch (error) {
10899
res.status(500).json({ error: getErrorMessage(error) });
109100
}
110-
},
101+
}
111102
);
112103

113104
/* Emails a password reset link to the user with the specified email */
@@ -118,10 +109,10 @@ authRouter.post(
118109
try {
119110
await authService.resetPassword(req.params.email);
120111
res.status(204).send();
121-
} catch (error: unknown) {
112+
} catch (error) {
122113
res.status(500).json({ error: getErrorMessage(error) });
123114
}
124-
},
115+
}
125116
);
126117

127118
// updates user password and updates status
@@ -132,7 +123,7 @@ authRouter.post(
132123
try {
133124
const responseSuccess = await authService.setPassword(
134125
req.params.email,
135-
req.body.newPassword,
126+
req.body.newPassword
136127
);
137128
if (responseSuccess.success) {
138129
const user = await userService.getUserByEmail(req.params.email);
@@ -149,15 +140,15 @@ authRouter.post(
149140
} catch (error) {
150141
res.status(500).json({ error: getErrorMessage(error) });
151142
}
152-
},
143+
}
153144
);
154145

155146
/* Invite a user */
156147
authRouter.post("/invite-user", inviteUserDtoValidator, async (req, res) => {
157148
try {
158149
if (
159150
!isAuthorizedByRole(
160-
new Set([Role.ADMINISTRATOR, Role.ANIMAL_BEHAVIOURIST]),
151+
new Set([Role.ADMINISTRATOR, Role.ANIMAL_BEHAVIOURIST])
161152
)
162153
) {
163154
res
@@ -184,7 +175,7 @@ authRouter.post("/invite-user", inviteUserDtoValidator, async (req, res) => {
184175
await userService.updateUserById(user.id, invitedUser);
185176

186177
res.status(204).send();
187-
} catch (error: unknown) {
178+
} catch (error) {
188179
if (error instanceof NotFoundError) {
189180
res.status(404).send(getErrorMessage(error));
190181
} else {

backend/typescript/services/implementations/authService.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,40 +38,6 @@ class AuthService implements IAuthService {
3838
}
3939
}
4040

41-
/* eslint-disable class-methods-use-this */
42-
async generateTokenOAuth(idToken: string): Promise<AuthDTO> {
43-
try {
44-
const googleUser = await FirebaseRestClient.signInWithGoogleOAuth(
45-
idToken,
46-
);
47-
// googleUser.idToken refers to the Firebase Auth access token for the user
48-
const token = {
49-
accessToken: googleUser.idToken,
50-
refreshToken: googleUser.refreshToken,
51-
};
52-
// If user already has a login with this email, just return the token
53-
try {
54-
// Note: an error message will be logged from UserService if this lookup fails.
55-
// You may want to silence the logger for this special OAuth user lookup case
56-
const user = await this.userService.getUserByEmail(googleUser.email);
57-
return { ...token, ...user };
58-
/* eslint-disable-next-line no-empty */
59-
} catch (error) {}
60-
61-
const user = await this.userService.createUser({
62-
firstName: googleUser.firstName,
63-
lastName: googleUser.lastName,
64-
email: googleUser.email,
65-
role: Role.STAFF,
66-
});
67-
68-
return { ...token, ...user };
69-
} catch (error) {
70-
Logger.error(`Failed to generate token for user with OAuth ID token`);
71-
throw error;
72-
}
73-
}
74-
7541
async revokeTokens(userId: string): Promise<void> {
7642
try {
7743
const authId = await this.userService.getAuthIdById(userId);

backend/typescript/services/interfaces/authService.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ interface IAuthService {
1111
*/
1212
generateToken(email: string, password: string): Promise<AuthDTO>;
1313

14-
/**
15-
* Generate a short-lived JWT access token and a long-lived refresh token
16-
* when supplied OAuth ID token
17-
* @param idToken user's ID token
18-
* @returns AuthDTO object containing the access token, refresh token, and user info
19-
* @throws Error if token generation fails
20-
*/
21-
generateTokenOAuth(idToken: string): Promise<AuthDTO>;
22-
2314
/**
2415
* Revoke all refresh tokens of a user
2516
* @param userId userId of user whose refresh tokens are to be revoked

backend/typescript/utilities/firebaseRestClient.ts

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ const FIREBASE_SIGN_IN_URL =
99
"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword";
1010
const FIREBASE_REFRESH_TOKEN_URL =
1111
"https://securetoken.googleapis.com/v1/token";
12-
const FIREBASE_OAUTH_SIGN_IN_URL =
13-
"https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp";
1412

1513
type PasswordSignInResponse = {
1614
idToken: string;
@@ -21,26 +19,6 @@ type PasswordSignInResponse = {
2119
registered: boolean;
2220
};
2321

24-
type OAuthSignInResponse = {
25-
federatedId: string;
26-
providerId: string;
27-
localId: string;
28-
emailVerified: boolean;
29-
email: string;
30-
oauthIdToken: string;
31-
oauthAccessToken: string;
32-
oauthTokenSecret: string;
33-
rawUserInfo: string;
34-
firstName: string;
35-
lastName: string;
36-
fullName: string;
37-
displayName: string;
38-
photoUrl: string;
39-
idToken: string;
40-
refreshToken: string;
41-
expiresIn: string;
42-
needConfirmation: boolean;
43-
};
4422

4523
type RefreshTokenResponse = {
4624
expires_in: string;
@@ -103,45 +81,6 @@ const FirebaseRestClient = {
10381
};
10482
},
10583

106-
// Docs: https://firebase.google.com/docs/reference/rest/auth/#section-sign-in-with-oauth-credential
107-
signInWithGoogleOAuth: async (
108-
idToken: string,
109-
): Promise<OAuthSignInResponse> => {
110-
const response: Response = await fetch(
111-
`${FIREBASE_OAUTH_SIGN_IN_URL}?key=${process.env.FIREBASE_WEB_API_KEY}`,
112-
{
113-
method: "POST",
114-
headers: {
115-
"Content-Type": "application/json",
116-
},
117-
body: JSON.stringify({
118-
postBody: `id_token=${idToken}&providerId=google.com`,
119-
requestUri: process.env.FIREBASE_REQUEST_URI,
120-
returnIdpCredential: true,
121-
returnSecureToken: true,
122-
}),
123-
},
124-
);
125-
126-
const responseJson:
127-
| OAuthSignInResponse
128-
| RequestError = await response.json();
129-
130-
if (!response.ok) {
131-
const errorMessage = [
132-
"Failed to sign-in via Firebase REST API with OAuth, status code =",
133-
`${response.status},`,
134-
"error message =",
135-
(responseJson as RequestError).error.message,
136-
];
137-
Logger.error(errorMessage.join(" "));
138-
139-
throw new Error("Failed to sign-in via Firebase REST API");
140-
}
141-
142-
return responseJson as OAuthSignInResponse;
143-
},
144-
14584
// Docs: https://firebase.google.com/docs/reference/rest/auth/#section-refresh-token
14685
refreshToken: async (refreshToken: string): Promise<Token> => {
14786
const response: Response = await fetch(

0 commit comments

Comments
 (0)