Skip to content

FT-googleAuthatication-#184359073 #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14,352 changes: 14,352 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
"jsonwebtoken": "^9.0.0",
"nock": "^13.3.0",
"nodemailer": "^6.9.1",
"passport": "^0.6.0",
"passport-google-oauth2": "^0.2.0",
"pg": "^8.9.0",
"pg-hstore": "^2.3.4",
"redis": "^4.6.4",
Expand All @@ -58,10 +60,13 @@
"devDependencies": {
"@types/bcrypt": "^5.0.0",
"@types/express": "^4.17.16",
"@types/express-session": "^1.17.6",
"@types/jest": "^29.4.0",
"@types/jsonwebtoken": "^9.0.1",
"@types/nodemailer": "^6.4.7",
"@types/passport": "^1.0.12",
"@types/supertest": "^2.0.12",
"@types/swagger-jsdoc": "^6.0.1",
"@types/swagger-ui-express": "^4.1.3",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
Expand Down
17 changes: 15 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,21 @@ import {config} from 'dotenv'
import swaggerDocs from './docs/swagger'
import connectdb from './db/database'
import authRoutes from './routes/authroutes'
import profileRoutes from "./routes/profileroutes"
import profileRoutes from './routes/profileroutes'
import passport from 'passport'
import session from 'express-session'

const app: Application = express()
import './config/googlePassport.config'
app.use(
session({
secret: `process.env.SECRET`,
resave: false,
saveUninitialized: true,
}),
)
app.use(passport.initialize())
app.use(passport.session())

config()
//middleware section
Expand All @@ -23,4 +36,4 @@ connectdb().then(() => {
// change this to just port in case someone is listening from 127.0.0.1 instead of localhost
})

export default app
export default app
22 changes: 22 additions & 0 deletions src/config/googlePassport.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const passport = require('passport')
const GoogleStrategy = require('passport-google-oauth2').Strategy
require('dotenv').config()
passport.use(
new GoogleStrategy(
{
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: process.env.CallBackURL,
passReqToCallBack: true,
},
function (request, accessToken, refreshToken, profile, done) {
return done(null, profile)
},
),
)
passport.serializeUser((user, done) => {
done(null, user)
})
passport.deserializeUser((user, done) => {
done(null, user)
})
124 changes: 82 additions & 42 deletions src/controllers/__tests__/authController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,35 @@ import supertest from 'supertest'
import app from '../../app'
import USER from '../../models/User'
import Tokens from '../../models/token'
import {httpRequest, httpResponse} from '../mock/user.mock'
import GoogleController from '../googleAuthController'
jest.setTimeout(20000)
describe('Login via google', () => {
afterAll(async () => {
USER.destroy({
where: {email: '[email protected]'},
})
})
test('redirect to google and authenticate', async () => {
const data = await GoogleController.googleAuth(
httpRequest('[email protected]'),
httpResponse(),
)
expect(data.body).toHaveProperty('user')
})

test('testing register', async () => {
const data: any = await GoogleController.googleAuth(
httpRequest('[email protected]'),
httpResponse(),
)
expect(data.body).toHaveProperty('user')
})
test('testing 500', async () => {
const data: any = await GoogleController.googleAuth('helll', httpResponse())
expect(data.body.status).toBe(500)
})
})

/* eslint-disable @typescript-eslint/no-explicit-any */
describe('Math functions', () => {
Expand All @@ -18,48 +47,59 @@ describe('Math functions', () => {
})
})
// reset password coontroller tests
describe('reset password',()=>{
describe('send link to email' , ()=>{
test('incase of unregistered email', async ()=>{
const response = await supertest(app).post("/resetpassword/link").send({email: "[email protected]"})
describe('reset password', () => {
describe('send link to email', () => {
test('incase of unregistered email', async () => {
const response = await supertest(app)
.post('/resetpassword/link')
.send({email: '[email protected]'})
expect(response.status).toBe(400)
}, 10000)// timeout 10 seconds
}, 10000) // timeout 10 seconds
})
test('incase of a registered email', async ()=>{
const response = await supertest(app).post("/resetpassword/link").send({email: "[email protected]"})
expect(response.status).toBe(200)
}, 20000)
test('incase invalid email input', async ()=>{
const response = await supertest(app).post("/resetpassword/link").send({email: "rukundjoseph"})
expect(response.status).toBe(400)
}, 20000)
describe('add token and change password',()=>{
test('incase incorrect token', async ()=>{
const response = await supertest(app).patch("/changepassword/[email protected]/65328dba23").send({newpassword : "newpassword",
confirmpass: "newpassword"})
test('incase of a registered email', async () => {
const response = await supertest(app)
.post('/resetpassword/link')
.send({email: '[email protected]'})
expect(response.status).toBe(200)
}, 20000)
test('incase invalid email input', async () => {
const response = await supertest(app)
.post('/resetpassword/link')
.send({email: 'rukundjoseph'})
expect(response.status).toBe(400)
}, 20000)
describe('add token and change password', () => {
test('incase incorrect token', async () => {
const response = await supertest(app)
.patch('/changepassword/[email protected]/65328dba23')
.send({newpassword: 'newpassword', confirmpass: 'newpassword'})
expect(response.status).toBe(400)
}, 20000)
test('incase incorrect token', async ()=>{
const response = await supertest(app).patch("/changepassword/[email protected]/65328dba23").send({newpassword : "newpassword",
confirmpass: "newpassword"})
expect(response.status).toBe(400)
}, 20000)
test('incase of a unmatching passwords', async ()=>{
const user: any = await USER.findOne({where: {email: "[email protected]"}})
const token: any = await Tokens.findOne({where: {userId: `${user.id}`}})
const response = await supertest(app).patch(`/changepassword/[email protected]/${token.token}`).send({newpassword : "newpas",
confirmpass: "newpaa"})
expect(response.status).toBe(400)
})
test('incase of a valid token and email', async ()=>{
const user: any = await USER.findOne({where: {email: "[email protected]"}})
const token: any = await Tokens.findOne({where: {userId: `${user.id}`}})
const response = await supertest(app).patch(`/changepassword/[email protected]/${token.token}`).send({newpassword : "newpas",
confirmpass: "newpas"})
expect(response.status).toBe(200)
})

})
})


}, 20000)
test('incase incorrect token', async () => {
const response = await supertest(app)
.patch('/changepassword/[email protected]/65328dba23')
.send({newpassword: 'newpassword', confirmpass: 'newpassword'})
expect(response.status).toBe(400)
}, 20000)
test('incase of a unmatching passwords', async () => {
const user: any = await USER.findOne({
where: {email: '[email protected]'},
})
const token: any = await Tokens.findOne({where: {userId: `${user.id}`}})
const response = await supertest(app)
.patch(`/changepassword/[email protected]/${token.token}`)
.send({newpassword: 'newpas', confirmpass: 'newpaa'})
expect(response.status).toBe(400)
})
test('incase of a valid token and email', async () => {
const user: any = await USER.findOne({
where: {email: '[email protected]'},
})
const token: any = await Tokens.findOne({where: {userId: `${user.id}`}})
const response = await supertest(app)
.patch(`/changepassword/[email protected]/${token.token}`)
.send({newpassword: 'newpas', confirmpass: 'newpas'})
expect(response.status).toBe(200)
})
})
})
50 changes: 50 additions & 0 deletions src/controllers/googleAuthController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import User from '../models/User'
import bcrypyt from 'bcrypt'
import jwt from 'jsonwebtoken'
import {randomUUID} from 'crypto'

class GoogleController {
static async googleAuth(req: any, res: any) {
try {
await User.findOne({
where: {
email: req.user.email,
},
}).then(async (result: any) => {
if (result) {
res.status(200).json({
success: true,
user: {
id: result.id,
firstName: result.firstName,
lastName: result.lastName,
email: result.email,
token: generateToken(result),
},
})
} else {
const salt = await bcrypyt.genSalt(10)
const rand = randomUUID()
const hashpassword = await bcrypyt.hash(generateToken(rand), salt)
const user = await User.create({
firstName: req.user.name.givenName,
lastName: req.user.name.familyName,
email: req.user.email,
password: hashpassword,
})
await user.save()

return res.status(200).json({user: user})
}
})
return res
} catch (error) {
return res.status(500).json({status: 500, error: error})
}
}
}

const generateToken = (user) => {
return jwt.sign({user}, 'my-token-secret', {expiresIn: '30d'})
}
export default GoogleController
28 changes: 28 additions & 0 deletions src/controllers/mock/user.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export const httpRequest = (email) => ({
user: {
id: '1',
email,
name: {
familyName: 'request',
middleName: 'request',
givenName: 'request',
},
firstName: 'firstName',
lastName: 'lastName',
role: 'buyer',
},
})

export const httpResponse = () => {
const res: any = {
json: (data) => {
res.body = data
return res
},
status: (data) => {
res.body = data
return res
},
}
return res
}
Loading