-
-
Notifications
You must be signed in to change notification settings - Fork 27
/
google.ts
73 lines (63 loc) · 1.97 KB
/
google.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/* SPDX-FileCopyrightText: 2016-present Kriasoft <hello@kriasoft.com> */
/* SPDX-License-Identifier: MIT */
import { RequestHandler } from "express";
import { OAuth2Client } from "google-auth-library";
import { IdentityProvider } from "../db";
import env from "../env";
import authorize from "./authorize";
/**
* OAuth 2.0 client for Google.
*/
const oauth = new OAuth2Client({
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
});
/**
* Redirects user to Google login page.
*/
export const redirect: RequestHandler = function (req, res) {
const authorizeUrl = oauth.generateAuthUrl({
access_type: "offline",
scope: [
"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/userinfo.email",
"openid",
],
include_granted_scopes: true,
redirect_uri: req.app.locals.redirect_uri,
});
res.redirect(authorizeUrl);
};
/**
* Obtains authorization tokens and profile information once the user
* returns from Facebook website.
*/
export const callback: RequestHandler = async function (req, res, next) {
try {
const { code } = req.query as { code: string };
const { redirect_uri } = req.app.locals;
const { tokens } = await oauth.getToken({ code, redirect_uri });
// Fetch profile information
const login = await oauth.verifyIdToken({
idToken: tokens.id_token as string,
});
const userId = login.getUserId();
const profile = login.getPayload();
if (!(profile && userId)) {
throw new Error();
}
// Link OAuth credentials with the user account.
const me = await authorize(req, {
id: userId,
provider: IdentityProvider.Google,
email: profile.email,
email_verified: profile.email_verified,
name: profile.name,
picture: profile.picture,
credentials: tokens as unknown as Record<string, string>,
});
res.render("auth-callback", { data: { me }, layout: false });
} catch (err) {
next(err);
}
};