File tree 6 files changed +161
-1
lines changed
Filter options
6 files changed +161
-1
lines changed
Original file line number Diff line number Diff line change 20
20
"typeorm" : " node --require ts-node/register ./node_modules/typeorm/cli.js"
21
21
},
22
22
"dependencies" : {
23
+ "axios" : " ^1.2.0" ,
23
24
"bcrypt" : " 5.0.1" ,
24
25
"compression" : " ^1.7.4" ,
25
26
"cors" : " ^2.8.5" ,
29
30
"express-passport-logout" : " ^0.1.0" ,
30
31
"joi" : " ^17.4.1" ,
31
32
"jsonwebtoken" : " ^8.5.1" ,
33
+ "node-fetch" : " ^2.6.1" ,
32
34
"passport" : " ^0.4.1" ,
33
35
"passport-jwt" : " ^4.0.0" ,
34
- "sqlite3" : " 5.0.2" ,
35
36
"pm2" : " ^5.1.0" ,
37
+ "sqlite3" : " 5.0.2" ,
36
38
"typeorm" : " 0.2.34"
37
39
},
38
40
"devDependencies" : {
42
44
"@types/express" : " ^4.17.13" ,
43
45
"@types/jest" : " ^26.0.24" ,
44
46
"@types/node" : " ^16.3.3" ,
47
+ "@types/node-fetch" : " ^2.6.2" ,
45
48
"@types/passport-jwt" : " ^3.0.6" ,
46
49
"@types/sqlite3" : " 3.1.7" ,
47
50
"@types/supertest" : " ^2.0.11" ,
Original file line number Diff line number Diff line change
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
+
Original file line number Diff line number Diff line change
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 ;
Original file line number Diff line number Diff line change @@ -12,6 +12,7 @@ import passport from 'passport';
12
12
13
13
import initPassport from '../config/passport' ;
14
14
import routes from '../routes/users' ;
15
+ import sessionRoute from '../routes/session.route'
15
16
import { connect } from './database' ;
16
17
17
18
// Instantiate express
@@ -32,5 +33,6 @@ server.use(express.json());
32
33
33
34
// Initialize routes middleware
34
35
server . use ( '/api/users' , routes ) ;
36
+ server . use ( '/api/sessions' , sessionRoute )
35
37
36
38
export default server ;
Original file line number Diff line number Diff line change
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
+ } ;
Original file line number Diff line number Diff line change
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
+ } ;
You can’t perform that action at this time.
0 commit comments