Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f99be6e

Browse filesBrowse files
committed
added github oauth
1 parent a0a0af4 commit f99be6e
Copy full SHA for f99be6e

File tree

6 files changed

+161
-1
lines changed
Filter options

6 files changed

+161
-1
lines changed

‎package.json

Copy file name to clipboardExpand all lines: package.json
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js"
2121
},
2222
"dependencies": {
23+
"axios": "^1.2.0",
2324
"bcrypt": "5.0.1",
2425
"compression": "^1.7.4",
2526
"cors": "^2.8.5",
@@ -29,10 +30,11 @@
2930
"express-passport-logout": "^0.1.0",
3031
"joi": "^17.4.1",
3132
"jsonwebtoken": "^8.5.1",
33+
"node-fetch": "^2.6.1",
3234
"passport": "^0.4.1",
3335
"passport-jwt": "^4.0.0",
34-
"sqlite3": "5.0.2",
3536
"pm2": "^5.1.0",
37+
"sqlite3": "5.0.2",
3638
"typeorm": "0.2.34"
3739
},
3840
"devDependencies": {
@@ -42,6 +44,7 @@
4244
"@types/express": "^4.17.13",
4345
"@types/jest": "^26.0.24",
4446
"@types/node": "^16.3.3",
47+
"@types/node-fetch": "^2.6.2",
4548
"@types/passport-jwt": "^3.0.6",
4649
"@types/sqlite3": "3.1.7",
4750
"@types/supertest": "^2.0.11",

‎src/controllers/auth.controller.ts

Copy file name to clipboard
+41Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Request, Response } from 'express';
2+
import {
3+
getGithubOathToken,
4+
getGithubUser,
5+
} from '../services/session.service';
6+
import { createUserWithToken } from '../services/user.service';
7+
8+
9+
export const githubOauthHandler = async (
10+
req: Request,
11+
res: Response,
12+
) => {
13+
try {
14+
const code = req.query.code as string;
15+
16+
if (req.query.error) {
17+
return res.redirect(`http://localhost:3000/login`);
18+
}
19+
20+
if (!code) {
21+
console.log('authorization code not provided')
22+
}
23+
24+
// Get access_token using code
25+
const { access_token } = await getGithubOathToken({ code });
26+
27+
// Get user details using access token
28+
const userData = await getGithubUser({access_token});
29+
30+
const returnedUser = await createUserWithToken(userData)
31+
if(returnedUser) {
32+
res.redirect(`http://localhost:3000`);
33+
}else {
34+
res.json({error: 'no user returned'})
35+
}
36+
37+
} catch (err: any) {
38+
res.json({'error': err.message})
39+
}
40+
};
41+

‎src/routes/session.route.ts

Copy file name to clipboard
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import express from 'express';
2+
import { githubOauthHandler } from '../controllers/auth.controller';
3+
4+
const router = express.Router();
5+
6+
router.get('/oauth/github', githubOauthHandler);
7+
8+
export default router;

‎src/server/index.ts

Copy file name to clipboardExpand all lines: src/server/index.ts
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import passport from 'passport';
1212

1313
import initPassport from '../config/passport';
1414
import routes from '../routes/users';
15+
import sessionRoute from '../routes/session.route'
1516
import { connect } from './database';
1617

1718
// Instantiate express
@@ -32,5 +33,6 @@ server.use(express.json());
3233

3334
// Initialize routes middleware
3435
server.use('/api/users', routes);
36+
server.use('/api/sessions', sessionRoute)
3537

3638
export default server;

‎src/services/session.service.ts

Copy file name to clipboard
+54Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import axios from 'axios';
2+
import qs from 'qs'
3+
import fetch from 'node-fetch'
4+
5+
type GitHubOauthToken = {
6+
access_token: string;
7+
};
8+
9+
export const getGithubOathToken = async ({
10+
code,
11+
}: {
12+
code: string;
13+
}): Promise<any> => {
14+
const rootUrl = 'https://github.com/login/oauth/access_token';
15+
const options = {
16+
client_id: process.env.GITHUB_OAUTH_CLIENT_ID,
17+
client_secret: process.env.GITHUB_OAUTH_CLIENT_SECRET,
18+
code,
19+
};
20+
21+
const queryString = qs.stringify(options);
22+
23+
try {
24+
const { data } = await axios.post(`${rootUrl}?${queryString}`, {
25+
headers: {
26+
'Content-Type': 'application/x-www-form-urlencoded',
27+
},
28+
});
29+
const decoded = qs.parse(data) as GitHubOauthToken;
30+
return decoded;
31+
} catch (err: any) {
32+
throw Error(err);
33+
}
34+
};
35+
36+
export const getGithubUser = async ({
37+
access_token,
38+
}: {
39+
access_token: string;
40+
}): Promise<any> => {
41+
try {
42+
const response = await fetch('https://api.github.com/user',{
43+
method: 'GET',
44+
headers: {
45+
Authorization: `Bearer ${access_token}`,
46+
},
47+
}
48+
);
49+
const data = await response.json()
50+
return data;
51+
} catch (err: any) {
52+
throw Error(err)
53+
}
54+
};

‎src/services/user.service.ts

Copy file name to clipboard
+52Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import jwt from "jsonwebtoken";
2+
import User from "../models/user";
3+
import ActiveSession from "../models/activeSession";
4+
import { connection } from "../server/database";
5+
6+
export const createUserWithToken = async (userData: any) => {
7+
const userRepository = connection!.getRepository(User);
8+
const activeSessionRepository = connection!.getRepository(ActiveSession);
9+
10+
const { login: username, email } = userData;
11+
let requiredUser: any = null;
12+
13+
const user = await userRepository.findOne({ username });
14+
15+
if (user) {
16+
requiredUser = user;
17+
} else {
18+
const query = {
19+
username,
20+
email: email ? email : "fullstackdev@gmail.com",
21+
password: "123",
22+
};
23+
userRepository.save(query).then((u) => {
24+
console.log("u", u);
25+
requiredUser = u;
26+
});
27+
}
28+
29+
if (!process.env.SECRET) {
30+
throw new Error("SECRET not provided");
31+
}
32+
33+
if (requiredUser) {
34+
const token: any = jwt.sign(
35+
{
36+
id: requiredUser.id,
37+
username: requiredUser.username,
38+
},
39+
process.env.SECRET,
40+
{
41+
expiresIn: 86400, // 1 week
42+
}
43+
);
44+
45+
const query = { userId: requiredUser.id, token };
46+
47+
console.log("query", query);
48+
activeSessionRepository.save(query);
49+
requiredUser.token = token;
50+
}
51+
return requiredUser;
52+
};

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.