Skip to content
This repository was archived by the owner on Apr 19, 2023. It is now read-only.

Commit c02c8cc

Browse files
✨ OAuth2
1 parent 84436dc commit c02c8cc

File tree

6 files changed

+75
-15
lines changed

6 files changed

+75
-15
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "staart",
3-
"version": "1.0.13",
3+
"version": "1.0.14",
44
"main": "index.js",
55
"repository": "git@github.com:AnandChowdhary/staart.git",
66
"author": "Anand Chowdhary <mail@anandchowdhary.com>",
@@ -76,6 +76,7 @@
7676
"dependencies": {
7777
"@hapi/joi": "^15.0.3",
7878
"@sentry/node": "^5.4.0",
79+
"axios": "^0.19.0",
7980
"bcryptjs": "^2.4.3",
8081
"body-parser": "^1.19.0",
8182
"client-oauth2": "^4.2.4",

src/controllers/auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
register,
1414
login2FA,
1515
github,
16-
oauthCallback
16+
githubCallback
1717
} from "../rest/auth";
1818
import { verifyToken } from "../helpers/jwt";
1919
import {
@@ -233,6 +233,6 @@ export class AuthController {
233233
@Post("oauth/github")
234234
async oauthGitHubCallback(req: Request, res: Response) {
235235
const code = getCodeFromRequest(req);
236-
res.json(await oauthCallback(github, code));
236+
res.json(await githubCallback(code, res.locals));
237237
}
238238
}

src/interfaces/enum.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export enum EventType {
2525
USER_DELETED = "user.deleted",
2626
AUTH_REFRESH = "auth.refresh",
2727
AUTH_LOGIN = "auth.login",
28+
AUTH_LOGIN_OAUTH = "auth.login_oauth",
2829
AUTH_LOGIN_BACKUP_CODE = "auth.login_backupCode",
2930
AUTH_LOGIN_GOOGLE = "auth.login_google",
3031
AUTH_PASSWORD_CHANGED = "auth.password_changed",
@@ -72,7 +73,8 @@ export enum ErrorCode {
7273
USER_IS_MEMBER_ALREADY = "400/user-is-member-already",
7374
STRIPE_NO_CUSTOMER = "404/no-customer",
7475
NOT_ENABLED_2FA = "400/invalid-2fa-token",
75-
INVALID_2FA_TOKEN = "401/invalid-2fa-token"
76+
INVALID_2FA_TOKEN = "401/invalid-2fa-token",
77+
OAUTH_NO_EMAIL = "404/oauth-no-email"
7678
}
7779

7880
export enum Templates {

src/interfaces/oauth.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface GitHubEmail {
2+
email: string;
3+
primary: boolean;
4+
verified: boolean;
5+
visibility?: "public" | "private";
6+
}

src/rest/auth.ts

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ import { can } from "../helpers/authorization";
4343
import { authenticator } from "otplib";
4444
import ClientOAuth2 from "client-oauth2";
4545
import { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } from "../config";
46+
import axios from "axios";
47+
import { GitHubEmail } from "../interfaces/oauth";
4648

4749
export const validateRefreshToken = async (token: string, locals: Locals) => {
4850
const data = <User>await verifyToken(token, Tokens.REFRESH);
@@ -199,22 +201,44 @@ export const approveLocation = async (token: string, locals: Locals) => {
199201
);
200202
};
201203

202-
// OAuth2 clients
204+
/*
205+
OAuth clients
206+
*/
207+
203208
export const github = new ClientOAuth2({
204209
clientId: GITHUB_CLIENT_ID,
205210
clientSecret: GITHUB_CLIENT_SECRET,
206211
accessTokenUri: "https://github.com/login/oauth/access_token",
207212
authorizationUri: "https://github.com/login/oauth/authorize",
208213
redirectUri: "https://staart-demo.o15y.com/auth/callback/github",
209-
scopes: ["user"]
214+
scopes: ["user:email"]
210215
});
211-
export const oauthCallback = async (service: ClientOAuth2, url: string) => {
212-
const response = await service.code.getToken(url);
213-
console.log("Got", response.data);
214-
return { hello: "hello world", data: response.data };
215-
// const email = response.data.email;
216-
// if (!email) throw new Error(ErrorCode.USER_NOT_FOUND);
217-
// const user = await getUserByEmail(email);
218-
// if (!user.id) throw new Error(ErrorCode.USER_NOT_FOUND);
219-
// return await getLoginResponse(user, EventType.AUTH_LOGIN, "github", locals);
216+
export const githubCallback = async (url: string, locals: Locals) => {
217+
const response = await github.code.getToken(url);
218+
const emails = ((await axios.get("https://api.github.com/user/emails", {
219+
headers: {
220+
Authorization: `token ${response.accessToken}`
221+
}
222+
})).data as GitHubEmail[]).filter(emails => (emails.verified = true));
223+
for await (const email of emails) {
224+
try {
225+
const user = await getUserByEmail(email.email);
226+
return await getLoginResponse(
227+
user,
228+
EventType.AUTH_LOGIN_OAUTH,
229+
"github",
230+
locals
231+
);
232+
} catch (error) {}
233+
}
234+
throw new Error(ErrorCode.OAUTH_NO_EMAIL);
220235
};
236+
237+
export const microsoft = new ClientOAuth2({
238+
clientId: GITHUB_CLIENT_ID,
239+
clientSecret: GITHUB_CLIENT_SECRET,
240+
accessTokenUri: "https://login.microsoftonline.com/common/oauth2/v2.0/token",
241+
authorizationUri: "https://www.facebook.com/v3.3/dialog/oauth",
242+
redirectUri: "https://staart-demo.o15y.com/auth/callback/microsoft",
243+
scopes: ["email"]
244+
});

yarn.lock

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,14 @@ aws4@^1.8.0:
16291629
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
16301630
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
16311631

1632+
axios@^0.19.0:
1633+
version "0.19.0"
1634+
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
1635+
integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
1636+
dependencies:
1637+
follow-redirects "1.5.10"
1638+
is-buffer "^2.0.2"
1639+
16321640
babel-jest@^24.8.0:
16331641
version "24.8.0"
16341642
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.8.0.tgz#5c15ff2b28e20b0f45df43fe6b7f2aae93dba589"
@@ -2309,6 +2317,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
23092317
dependencies:
23102318
ms "2.0.0"
23112319

2320+
debug@=3.1.0:
2321+
version "3.1.0"
2322+
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
2323+
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
2324+
dependencies:
2325+
ms "2.0.0"
2326+
23122327
debug@^3.1.0:
23132328
version "3.2.6"
23142329
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
@@ -2827,6 +2842,13 @@ find-up@^3.0.0:
28272842
dependencies:
28282843
locate-path "^3.0.0"
28292844

2845+
follow-redirects@1.5.10:
2846+
version "1.5.10"
2847+
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
2848+
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
2849+
dependencies:
2850+
debug "=3.1.0"
2851+
28302852
for-in@^1.0.2:
28312853
version "1.0.2"
28322854
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -3450,6 +3472,11 @@ is-buffer@^1.1.5, is-buffer@~1.1.1:
34503472
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
34513473
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
34523474

3475+
is-buffer@^2.0.2:
3476+
version "2.0.3"
3477+
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725"
3478+
integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==
3479+
34533480
is-callable@^1.1.4:
34543481
version "1.1.4"
34553482
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"

0 commit comments

Comments
 (0)