mirror of
https://github.com/sasjs/server.git
synced 2026-01-05 05:40:06 +00:00
chore: added incremental field 'id' in user collection
This commit is contained in:
82
package-lock.json
generated
82
package-lock.json
generated
@@ -14,6 +14,7 @@
|
|||||||
"joi": "^17.4.2",
|
"joi": "^17.4.2",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"mongoose": "^6.0.12",
|
"mongoose": "^6.0.12",
|
||||||
|
"mongoose-sequence": "^5.3.1",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.3",
|
"multer": "^1.4.3",
|
||||||
"swagger-ui-express": "^4.1.6",
|
"swagger-ui-express": "^4.1.6",
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
"@types/express": "^4.17.12",
|
"@types/express": "^4.17.12",
|
||||||
"@types/jest": "^26.0.24",
|
"@types/jest": "^26.0.24",
|
||||||
"@types/jsonwebtoken": "^8.5.5",
|
"@types/jsonwebtoken": "^8.5.5",
|
||||||
|
"@types/mongoose-sequence": "^3.0.6",
|
||||||
"@types/morgan": "^1.9.3",
|
"@types/morgan": "^1.9.3",
|
||||||
"@types/multer": "^1.4.7",
|
"@types/multer": "^1.4.7",
|
||||||
"@types/node": "^15.12.2",
|
"@types/node": "^15.12.2",
|
||||||
@@ -2399,6 +2401,25 @@
|
|||||||
"integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==",
|
"integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/mongoose": {
|
||||||
|
"version": "5.11.97",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.11.97.tgz",
|
||||||
|
"integrity": "sha512-cqwOVYT3qXyLiGw7ueU2kX9noE8DPGRY6z8eUxudhXY8NZ7DMKYAxyZkLSevGfhCX3dO/AoX5/SO9lAzfjon0Q==",
|
||||||
|
"deprecated": "Mongoose publishes its own types, so you do not need to install this package.",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"mongoose": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/mongoose-sequence": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mongoose-sequence/-/mongoose-sequence-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-S6DD4rSlSnUI9BQvR/ACtekpylSIm0pEKayG9NqOlkUo3Q/AZLBmdi0IozSGPQ8JcB2ZSm81nLdZPhTqyOqrQg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/mongoose": "^5.10.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/morgan": {
|
"node_modules/@types/morgan": {
|
||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz",
|
||||||
@@ -2824,6 +2845,14 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/async": {
|
||||||
|
"version": "2.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
|
||||||
|
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/async-mutex": {
|
"node_modules/async-mutex": {
|
||||||
"version": "0.3.2",
|
"version": "0.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz",
|
||||||
@@ -7684,8 +7713,7 @@
|
|||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/lodash.capitalize": {
|
"node_modules/lodash.capitalize": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
@@ -8258,6 +8286,18 @@
|
|||||||
"url": "https://opencollective.com/mongoose"
|
"url": "https://opencollective.com/mongoose"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mongoose-sequence": {
|
||||||
|
"version": "5.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mongoose-sequence/-/mongoose-sequence-5.3.1.tgz",
|
||||||
|
"integrity": "sha512-kQB1ctCdAQT8YdQzoHV0CpBRsO4RNVy03SOkzM6TQKBbGBs1ZgVS4UlKsuvBPaiPt9q5tKgQZvorGJ1awbHDqA==",
|
||||||
|
"dependencies": {
|
||||||
|
"async": "^2.5.0",
|
||||||
|
"lodash": "^4.17.20"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"mongoose": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mongoose/node_modules/ms": {
|
"node_modules/mongoose/node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
@@ -16077,6 +16117,24 @@
|
|||||||
"integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==",
|
"integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/mongoose": {
|
||||||
|
"version": "5.11.97",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.11.97.tgz",
|
||||||
|
"integrity": "sha512-cqwOVYT3qXyLiGw7ueU2kX9noE8DPGRY6z8eUxudhXY8NZ7DMKYAxyZkLSevGfhCX3dO/AoX5/SO9lAzfjon0Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"mongoose": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/mongoose-sequence": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mongoose-sequence/-/mongoose-sequence-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-S6DD4rSlSnUI9BQvR/ACtekpylSIm0pEKayG9NqOlkUo3Q/AZLBmdi0IozSGPQ8JcB2ZSm81nLdZPhTqyOqrQg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/mongoose": "^5.10.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/morgan": {
|
"@types/morgan": {
|
||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz",
|
||||||
@@ -16439,6 +16497,14 @@
|
|||||||
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"async": {
|
||||||
|
"version": "2.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
|
||||||
|
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"async-mutex": {
|
"async-mutex": {
|
||||||
"version": "0.3.2",
|
"version": "0.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz",
|
||||||
@@ -20154,8 +20220,7 @@
|
|||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"lodash.capitalize": {
|
"lodash.capitalize": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
@@ -20595,6 +20660,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mongoose-sequence": {
|
||||||
|
"version": "5.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mongoose-sequence/-/mongoose-sequence-5.3.1.tgz",
|
||||||
|
"integrity": "sha512-kQB1ctCdAQT8YdQzoHV0CpBRsO4RNVy03SOkzM6TQKBbGBs1ZgVS4UlKsuvBPaiPt9q5tKgQZvorGJ1awbHDqA==",
|
||||||
|
"requires": {
|
||||||
|
"async": "^2.5.0",
|
||||||
|
"lodash": "^4.17.20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"morgan": {
|
"morgan": {
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
"joi": "^17.4.2",
|
"joi": "^17.4.2",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"mongoose": "^6.0.12",
|
"mongoose": "^6.0.12",
|
||||||
|
"mongoose-sequence": "^5.3.1",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.3",
|
"multer": "^1.4.3",
|
||||||
"swagger-ui-express": "^4.1.6",
|
"swagger-ui-express": "^4.1.6",
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
"@types/express": "^4.17.12",
|
"@types/express": "^4.17.12",
|
||||||
"@types/jest": "^26.0.24",
|
"@types/jest": "^26.0.24",
|
||||||
"@types/jsonwebtoken": "^8.5.5",
|
"@types/jsonwebtoken": "^8.5.5",
|
||||||
|
"@types/mongoose-sequence": "^3.0.6",
|
||||||
"@types/morgan": "^1.9.3",
|
"@types/morgan": "^1.9.3",
|
||||||
"@types/multer": "^1.4.7",
|
"@types/multer": "^1.4.7",
|
||||||
"@types/node": "^15.12.2",
|
"@types/node": "^15.12.2",
|
||||||
|
|||||||
@@ -15,11 +15,13 @@ import bcrypt from 'bcryptjs'
|
|||||||
import User, { UserPayload } from '../model/User'
|
import User, { UserPayload } from '../model/User'
|
||||||
|
|
||||||
interface userResponse {
|
interface userResponse {
|
||||||
|
id: number
|
||||||
username: string
|
username: string
|
||||||
displayName: string
|
displayName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface userDetailsResponse {
|
interface userDetailsResponse {
|
||||||
|
id: number
|
||||||
displayName: string
|
displayName: string
|
||||||
username: string
|
username: string
|
||||||
isActive: boolean
|
isActive: boolean
|
||||||
@@ -34,10 +36,12 @@ export default class UserController {
|
|||||||
*/
|
*/
|
||||||
@Example<userResponse[]>([
|
@Example<userResponse[]>([
|
||||||
{
|
{
|
||||||
|
id: 123,
|
||||||
username: 'johnusername',
|
username: 'johnusername',
|
||||||
displayName: 'John'
|
displayName: 'John'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 456,
|
||||||
username: 'starkusername',
|
username: 'starkusername',
|
||||||
displayName: 'Stark'
|
displayName: 'Stark'
|
||||||
}
|
}
|
||||||
@@ -52,6 +56,7 @@ export default class UserController {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Example<userDetailsResponse>({
|
@Example<userDetailsResponse>({
|
||||||
|
id: 1234,
|
||||||
displayName: 'John Snow',
|
displayName: 'John Snow',
|
||||||
username: 'johnSnow01',
|
username: 'johnSnow01',
|
||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
@@ -64,42 +69,55 @@ export default class UserController {
|
|||||||
return createUser(body)
|
return createUser(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user properties - such as group memberships, userName, displayName.
|
||||||
|
* @param userId The user's identifier
|
||||||
|
* @example userId 1234
|
||||||
|
*/
|
||||||
|
@Get('{userId}')
|
||||||
|
public async getUser(@Path() userId: number): Promise<userDetailsResponse> {
|
||||||
|
return getUser(userId)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update user properties - such as displayName. Can be performed either by admins, or the user in question.
|
* Update user properties - such as displayName. Can be performed either by admins, or the user in question.
|
||||||
* @param username The user's identifier
|
* @param userId The user's identifier
|
||||||
* @example username "johnSnow01"
|
* @example userId "1234"
|
||||||
*/
|
*/
|
||||||
@Example<userDetailsResponse>({
|
@Example<userDetailsResponse>({
|
||||||
|
id: 1234,
|
||||||
displayName: 'John Snow',
|
displayName: 'John Snow',
|
||||||
username: 'johnSnow01',
|
username: 'johnSnow01',
|
||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
isActive: true
|
isActive: true
|
||||||
})
|
})
|
||||||
@Patch('{username}')
|
@Patch('{userId}')
|
||||||
public async updateUser(
|
public async updateUser(
|
||||||
@Path() username: string,
|
@Path() userId: number,
|
||||||
@Body() body: UserPayload
|
@Body() body: UserPayload
|
||||||
): Promise<userDetailsResponse> {
|
): Promise<userDetailsResponse> {
|
||||||
return updateUser(username, body)
|
return updateUser(userId, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a user. Can be performed either by admins, or the user in question.
|
* Delete a user. Can be performed either by admins, or the user in question.
|
||||||
* @param username The user's identifier
|
* @param userId The user's identifier
|
||||||
* @example username "johnSnow01"
|
* @example userId 1234
|
||||||
*/
|
*/
|
||||||
@Delete('{username}')
|
@Delete('{userId}')
|
||||||
public async deleteUser(
|
public async deleteUser(
|
||||||
@Path() username: string,
|
@Path() userId: number,
|
||||||
@Body() body: { password?: string },
|
@Body() body: { password?: string },
|
||||||
@Query() @Hidden() isAdmin: boolean = false
|
@Query() @Hidden() isAdmin: boolean = false
|
||||||
) {
|
) {
|
||||||
return deleteUser(username, isAdmin, body)
|
return deleteUser(userId, isAdmin, body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAllUsers = async () =>
|
const getAllUsers = async (): Promise<userResponse[]> =>
|
||||||
await User.find({}).select({ _id: 0, username: 1, displayName: 1 }).exec()
|
await User.find({})
|
||||||
|
.select({ _id: 0, id: 1, username: 1, displayName: 1 })
|
||||||
|
.exec()
|
||||||
|
|
||||||
const createUser = async (data: any): Promise<userDetailsResponse> => {
|
const createUser = async (data: any): Promise<userDetailsResponse> => {
|
||||||
const { displayName, username, password, isAdmin, isActive } = data
|
const { displayName, username, password, isAdmin, isActive } = data
|
||||||
@@ -123,26 +141,29 @@ const createUser = async (data: any): Promise<userDetailsResponse> => {
|
|||||||
|
|
||||||
const savedUser = await user.save()
|
const savedUser = await user.save()
|
||||||
|
|
||||||
return {
|
return savedUser
|
||||||
displayName: savedUser.displayName,
|
|
||||||
username: savedUser.username,
|
|
||||||
isAdmin: savedUser.isAdmin,
|
|
||||||
isActive: savedUser.isActive
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateUser = async (currentUsername: string, data: any) => {
|
const getUser = async (id: number) => {
|
||||||
|
const user = await User.findOne({ id })
|
||||||
|
.select({
|
||||||
|
_id: 0,
|
||||||
|
id: 1,
|
||||||
|
username: 1,
|
||||||
|
displayName: 1,
|
||||||
|
isAdmin: 1,
|
||||||
|
isActive: 1
|
||||||
|
})
|
||||||
|
.exec()
|
||||||
|
if (!user) throw new Error('User is not found.')
|
||||||
|
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateUser = async (id: number, data: any) => {
|
||||||
const { displayName, username, password, isAdmin, isActive } = data
|
const { displayName, username, password, isAdmin, isActive } = data
|
||||||
|
|
||||||
const params: any = { displayName, isAdmin, isActive }
|
const params: any = { displayName, username, isAdmin, isActive }
|
||||||
|
|
||||||
if (username && currentUsername !== username) {
|
|
||||||
// Checking if username is already in the database
|
|
||||||
const usernameExist = await User.findOne({ username })
|
|
||||||
if (usernameExist) throw new Error('Username already exists.')
|
|
||||||
|
|
||||||
params.username = username
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password) {
|
if (password) {
|
||||||
// Hash passwords
|
// Hash passwords
|
||||||
@@ -150,31 +171,31 @@ const updateUser = async (currentUsername: string, data: any) => {
|
|||||||
params.password = await bcrypt.hash(password, salt)
|
params.password = await bcrypt.hash(password, salt)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedUser = await User.findOneAndUpdate(
|
const updatedUser = await User.findOneAndUpdate({ id }, params, { new: true })
|
||||||
{ username: currentUsername },
|
.select({
|
||||||
params,
|
_id: 0,
|
||||||
{ new: true }
|
id: 1,
|
||||||
)
|
username: 1,
|
||||||
|
displayName: 1,
|
||||||
|
isAdmin: 1,
|
||||||
|
isActive: 1
|
||||||
|
})
|
||||||
|
.exec()
|
||||||
if (!updatedUser) throw new Error('Unable to update user')
|
if (!updatedUser) throw new Error('Unable to update user')
|
||||||
|
|
||||||
return {
|
return updatedUser
|
||||||
displayName: updatedUser.displayName,
|
|
||||||
username: updatedUser.username,
|
|
||||||
isAdmin: updatedUser.isAdmin,
|
|
||||||
isActive: updatedUser.isActive
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteUser = async (username: string, isAdmin: boolean, data: any) => {
|
const deleteUser = async (id: number, isAdmin: boolean, data: any) => {
|
||||||
const { password } = data
|
const { password } = data
|
||||||
|
|
||||||
const user = await User.findOne({ username })
|
const user = await User.findOne({ id })
|
||||||
if (!user) throw new Error('Username is not found.')
|
if (!user) throw new Error('User is not found.')
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
const validPass = await bcrypt.compare(password, user.password)
|
const validPass = await bcrypt.compare(password, user.password)
|
||||||
if (!validPass) throw new Error('Invalid password.')
|
if (!validPass) throw new Error('Invalid password.')
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.deleteOne({ username })
|
await User.deleteOne({ id })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const authenticateToken = (
|
|||||||
|
|
||||||
// verify this valid token's entry in DB
|
// verify this valid token's entry in DB
|
||||||
const user = await verifyTokenInDB(
|
const user = await verifyTokenInDB(
|
||||||
data?.username,
|
data?.userId,
|
||||||
data?.clientId,
|
data?.clientId,
|
||||||
token,
|
token,
|
||||||
tokenType
|
tokenType
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
export const verifyAdminIfNeeded = (req: any, res: any, next: any) => {
|
export const verifyAdminIfNeeded = (req: any, res: any, next: any) => {
|
||||||
const { user } = req
|
const { user } = req
|
||||||
const { username } = req.params
|
const { userId } = req.params
|
||||||
|
|
||||||
if (!user.isAdmin && user.username !== username) {
|
if (!user.isAdmin && user.id !== userId) {
|
||||||
return res.status(401).send('Admin account required')
|
return res.status(401).send('Admin account required')
|
||||||
}
|
}
|
||||||
next()
|
next()
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { Schema, model } from 'mongoose'
|
import { number } from 'joi'
|
||||||
|
import mongoose, { Schema, model } from 'mongoose'
|
||||||
|
const AutoIncrement = require('mongoose-sequence')(mongoose)
|
||||||
|
|
||||||
export interface UserPayload {
|
export interface UserPayload {
|
||||||
/**
|
/**
|
||||||
@@ -27,50 +29,52 @@ export interface UserPayload {
|
|||||||
isActive?: boolean
|
isActive?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserSchema extends UserPayload {
|
interface User extends UserPayload {
|
||||||
|
id: number
|
||||||
isAdmin: boolean
|
isAdmin: boolean
|
||||||
isActive: boolean
|
isActive: boolean
|
||||||
tokens: [{ [key: string]: string }]
|
tokens: [{ [key: string]: string }]
|
||||||
}
|
}
|
||||||
|
|
||||||
export default model(
|
const UserSchema = new Schema<User>({
|
||||||
'User',
|
displayName: {
|
||||||
new Schema<UserSchema>({
|
type: String,
|
||||||
displayName: {
|
required: true
|
||||||
type: String,
|
},
|
||||||
required: true
|
username: {
|
||||||
},
|
type: String,
|
||||||
username: {
|
required: true,
|
||||||
type: String,
|
unique: true
|
||||||
required: true
|
},
|
||||||
},
|
password: {
|
||||||
password: {
|
type: String,
|
||||||
type: String,
|
required: true
|
||||||
required: true
|
},
|
||||||
},
|
isAdmin: {
|
||||||
isAdmin: {
|
type: Boolean,
|
||||||
type: Boolean,
|
default: false
|
||||||
default: false
|
},
|
||||||
},
|
isActive: {
|
||||||
isActive: {
|
type: Boolean,
|
||||||
type: Boolean,
|
default: true
|
||||||
default: true
|
},
|
||||||
},
|
tokens: [
|
||||||
tokens: [
|
{
|
||||||
{
|
clientId: {
|
||||||
clientId: {
|
type: String,
|
||||||
type: String,
|
required: true
|
||||||
required: true
|
},
|
||||||
},
|
accessToken: {
|
||||||
accessToken: {
|
type: String,
|
||||||
type: String,
|
required: true
|
||||||
required: true
|
},
|
||||||
},
|
refreshToken: {
|
||||||
refreshToken: {
|
type: String,
|
||||||
type: String,
|
required: true
|
||||||
required: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
})
|
]
|
||||||
)
|
})
|
||||||
|
UserSchema.plugin(AutoIncrement, { inc_field: 'id' })
|
||||||
|
|
||||||
|
export default model('User', UserSchema)
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ export const connectDB = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const saveCode = (username: string, clientId: string, code: string) => {
|
export const saveCode = (userId: number, clientId: string, code: string) => {
|
||||||
if (authCodes[username]) return (authCodes[username][clientId] = code)
|
if (authCodes[userId]) return (authCodes[userId][clientId] = code)
|
||||||
|
|
||||||
authCodes[username] = { [clientId]: code }
|
authCodes[userId] = { [clientId]: code }
|
||||||
return authCodes[username][clientId]
|
return authCodes[userId][clientId]
|
||||||
}
|
}
|
||||||
export const deleteCode = (username: string, clientId: string) =>
|
export const deleteCode = (userId: number, clientId: string) =>
|
||||||
delete authCodes[username][clientId]
|
delete authCodes[userId][clientId]
|
||||||
|
|
||||||
authRouter.post('/authorize', async (req, res) => {
|
authRouter.post('/authorize', async (req, res) => {
|
||||||
const { error, value } = authorizeValidation(req.body)
|
const { error, value } = authorizeValidation(req.body)
|
||||||
@@ -76,10 +76,10 @@ authRouter.post('/authorize', async (req, res) => {
|
|||||||
// generate authorization code against clientId
|
// generate authorization code against clientId
|
||||||
const userInfo: InfoJWT = {
|
const userInfo: InfoJWT = {
|
||||||
clientId,
|
clientId,
|
||||||
username
|
userId: user.id
|
||||||
}
|
}
|
||||||
|
|
||||||
const code = saveCode(username, clientId, generateAuthCode(userInfo))
|
const code = saveCode(user.id, clientId, generateAuthCode(userInfo))
|
||||||
|
|
||||||
res.json({ code })
|
res.json({ code })
|
||||||
})
|
})
|
||||||
@@ -93,10 +93,9 @@ authRouter.post('/token', async (req, res) => {
|
|||||||
const userInfo = await verifyAuthCode(clientId, code)
|
const userInfo = await verifyAuthCode(clientId, code)
|
||||||
if (!userInfo) return res.sendStatus(403)
|
if (!userInfo) return res.sendStatus(403)
|
||||||
|
|
||||||
if (authCodes[userInfo.username][clientId] !== code)
|
if (authCodes[userInfo.userId][clientId] !== code) return res.sendStatus(403)
|
||||||
return res.sendStatus(403)
|
|
||||||
|
|
||||||
deleteCode(userInfo.username, clientId)
|
deleteCode(userInfo.userId, clientId)
|
||||||
|
|
||||||
const accessToken = generateAccessToken(userInfo)
|
const accessToken = generateAccessToken(userInfo)
|
||||||
const refreshToken = jwt.sign(
|
const refreshToken = jwt.sign(
|
||||||
@@ -104,15 +103,15 @@ authRouter.post('/token', async (req, res) => {
|
|||||||
process.env.REFRESH_TOKEN_SECRET as string
|
process.env.REFRESH_TOKEN_SECRET as string
|
||||||
)
|
)
|
||||||
|
|
||||||
await saveTokensInDB(userInfo.username, clientId, accessToken, refreshToken)
|
await saveTokensInDB(userInfo.userId, clientId, accessToken, refreshToken)
|
||||||
|
|
||||||
res.json({ accessToken: accessToken, refreshToken: refreshToken })
|
res.json({ accessToken: accessToken, refreshToken: refreshToken })
|
||||||
})
|
})
|
||||||
|
|
||||||
authRouter.post('/refresh', authenticateRefreshToken, async (req: any, res) => {
|
authRouter.post('/refresh', authenticateRefreshToken, async (req: any, res) => {
|
||||||
const { username, clientId } = req.user
|
const { userId, clientId } = req.user
|
||||||
const userInfo = {
|
const userInfo = {
|
||||||
username,
|
userId,
|
||||||
clientId
|
clientId
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +121,7 @@ authRouter.post('/refresh', authenticateRefreshToken, async (req: any, res) => {
|
|||||||
process.env.REFRESH_TOKEN_SECRET as string
|
process.env.REFRESH_TOKEN_SECRET as string
|
||||||
)
|
)
|
||||||
|
|
||||||
await saveTokensInDB(userInfo.username, clientId, accessToken, refreshToken)
|
await saveTokensInDB(userInfo.userId, clientId, accessToken, refreshToken)
|
||||||
|
|
||||||
res.json({ accessToken: accessToken, refreshToken: refreshToken })
|
res.json({ accessToken: accessToken, refreshToken: refreshToken })
|
||||||
})
|
})
|
||||||
@@ -160,7 +159,7 @@ const verifyAuthCode = async (
|
|||||||
|
|
||||||
const clientInfo: InfoJWT = {
|
const clientInfo: InfoJWT = {
|
||||||
clientId: data?.clientId,
|
clientId: data?.clientId,
|
||||||
username: data?.username
|
userId: data?.userId
|
||||||
}
|
}
|
||||||
if (clientInfo.clientId === clientId) {
|
if (clientInfo.clientId === clientId) {
|
||||||
return resolve(clientInfo)
|
return resolve(clientInfo)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { saveTokensInDB, verifyTokenInDB } from '../../../utils'
|
|||||||
const clientId = 'someclientID'
|
const clientId = 'someclientID'
|
||||||
const clientSecret = 'someclientSecret'
|
const clientSecret = 'someclientSecret'
|
||||||
const user = {
|
const user = {
|
||||||
|
id: 1234,
|
||||||
displayName: 'Test User',
|
displayName: 'Test User',
|
||||||
username: 'testUsername',
|
username: 'testUsername',
|
||||||
password: '87654321',
|
password: '87654321',
|
||||||
@@ -153,7 +154,7 @@ describe('auth', () => {
|
|||||||
describe('token', () => {
|
describe('token', () => {
|
||||||
const userInfo: InfoJWT = {
|
const userInfo: InfoJWT = {
|
||||||
clientId,
|
clientId,
|
||||||
username: user.username
|
userId: user.id
|
||||||
}
|
}
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await userController.createUser(user)
|
await userController.createUser(user)
|
||||||
@@ -166,7 +167,7 @@ describe('auth', () => {
|
|||||||
|
|
||||||
it('should respond with access and refresh tokens', async () => {
|
it('should respond with access and refresh tokens', async () => {
|
||||||
const code = saveCode(
|
const code = saveCode(
|
||||||
userInfo.username,
|
userInfo.userId,
|
||||||
userInfo.clientId,
|
userInfo.clientId,
|
||||||
generateAuthCode(userInfo)
|
generateAuthCode(userInfo)
|
||||||
)
|
)
|
||||||
@@ -197,7 +198,7 @@ describe('auth', () => {
|
|||||||
|
|
||||||
it('should respond with Bad Request if clientId is missing', async () => {
|
it('should respond with Bad Request if clientId is missing', async () => {
|
||||||
const code = saveCode(
|
const code = saveCode(
|
||||||
userInfo.username,
|
userInfo.userId,
|
||||||
userInfo.clientId,
|
userInfo.clientId,
|
||||||
generateAuthCode(userInfo)
|
generateAuthCode(userInfo)
|
||||||
)
|
)
|
||||||
@@ -227,7 +228,7 @@ describe('auth', () => {
|
|||||||
|
|
||||||
it('should respond with Forbidden if clientId is invalid', async () => {
|
it('should respond with Forbidden if clientId is invalid', async () => {
|
||||||
const code = saveCode(
|
const code = saveCode(
|
||||||
userInfo.username,
|
userInfo.userId,
|
||||||
userInfo.clientId,
|
userInfo.clientId,
|
||||||
generateAuthCode(userInfo)
|
generateAuthCode(userInfo)
|
||||||
)
|
)
|
||||||
@@ -245,14 +246,21 @@ describe('auth', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('refresh', () => {
|
describe('refresh', () => {
|
||||||
const refreshToken = generateRefreshToken({
|
let refreshToken: string
|
||||||
clientId,
|
let currentUser: any
|
||||||
username: user.username
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await userController.createUser(user)
|
currentUser = await userController.createUser(user)
|
||||||
await saveTokensInDB(user.username, clientId, 'accessToken', refreshToken)
|
refreshToken = generateRefreshToken({
|
||||||
|
clientId,
|
||||||
|
userId: currentUser.id
|
||||||
|
})
|
||||||
|
await saveTokensInDB(
|
||||||
|
currentUser.id,
|
||||||
|
clientId,
|
||||||
|
'accessToken',
|
||||||
|
refreshToken
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -289,14 +297,22 @@ describe('auth', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('logout', () => {
|
describe('logout', () => {
|
||||||
const accessToken = generateAccessToken({
|
let accessToken: string
|
||||||
clientId,
|
let currentUser: any
|
||||||
username: user.username
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await userController.createUser(user)
|
currentUser = await userController.createUser(user)
|
||||||
await saveTokensInDB(user.username, clientId, accessToken, 'refreshToken')
|
accessToken = generateAccessToken({
|
||||||
|
clientId,
|
||||||
|
userId: currentUser.id
|
||||||
|
})
|
||||||
|
|
||||||
|
await saveTokensInDB(
|
||||||
|
currentUser.id,
|
||||||
|
clientId,
|
||||||
|
accessToken,
|
||||||
|
'refreshToken'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -322,7 +338,7 @@ describe('auth', () => {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
await verifyTokenInDB(
|
await verifyTokenInDB(
|
||||||
user.username,
|
currentUser.id,
|
||||||
clientId,
|
clientId,
|
||||||
accessToken,
|
accessToken,
|
||||||
'accessToken'
|
'accessToken'
|
||||||
|
|||||||
@@ -40,15 +40,17 @@ describe('client', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('create', () => {
|
describe('create', () => {
|
||||||
const adminAccessToken = generateAccessToken({
|
let adminAccessToken: string
|
||||||
clientId: client.clientId,
|
let dbUser: any
|
||||||
username: adminUser.username
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await userController.createUser(adminUser)
|
dbUser = await userController.createUser(adminUser)
|
||||||
|
adminAccessToken = generateAccessToken({
|
||||||
|
clientId: client.clientId,
|
||||||
|
userId: dbUser.id
|
||||||
|
})
|
||||||
await saveTokensInDB(
|
await saveTokensInDB(
|
||||||
adminUser.username,
|
dbUser.id,
|
||||||
client.clientId,
|
client.clientId,
|
||||||
adminAccessToken,
|
adminAccessToken,
|
||||||
'refreshToken'
|
'refreshToken'
|
||||||
@@ -90,13 +92,13 @@ describe('client', () => {
|
|||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
isActive: true
|
isActive: true
|
||||||
}
|
}
|
||||||
|
const dbUser = await userController.createUser(user)
|
||||||
const accessToken = generateAccessToken({
|
const accessToken = generateAccessToken({
|
||||||
clientId: client.clientId,
|
clientId: client.clientId,
|
||||||
username: user.username
|
userId: dbUser.id
|
||||||
})
|
})
|
||||||
await userController.createUser(user)
|
|
||||||
await saveTokensInDB(
|
await saveTokensInDB(
|
||||||
user.username,
|
dbUser.id,
|
||||||
client.clientId,
|
client.clientId,
|
||||||
accessToken,
|
accessToken,
|
||||||
'refreshToken'
|
'refreshToken'
|
||||||
|
|||||||
@@ -35,14 +35,16 @@ describe('files', () => {
|
|||||||
await mongoServer.stop()
|
await mongoServer.stop()
|
||||||
})
|
})
|
||||||
describe('deploy', () => {
|
describe('deploy', () => {
|
||||||
const accessToken = generateAccessToken({
|
let accessToken: string
|
||||||
clientId,
|
let dbUser: any
|
||||||
username: user.username
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await controller.createUser(user)
|
dbUser = await controller.createUser(user)
|
||||||
await saveTokensInDB(user.username, clientId, accessToken, 'refreshToken')
|
accessToken = generateAccessToken({
|
||||||
|
clientId,
|
||||||
|
userId: dbUser.id
|
||||||
|
})
|
||||||
|
await saveTokensInDB(dbUser.id, clientId, accessToken, 'refreshToken')
|
||||||
})
|
})
|
||||||
const shouldFailAssertion = async (payload: any) => {
|
const shouldFailAssertion = async (payload: any) => {
|
||||||
const res = await request(app)
|
const res = await request(app)
|
||||||
|
|||||||
@@ -39,15 +39,16 @@ describe('user', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('create', () => {
|
describe('create', () => {
|
||||||
const adminAccessToken = generateAccessToken({
|
let adminAccessToken: string
|
||||||
clientId,
|
|
||||||
username: adminUser.username
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await controller.createUser(adminUser)
|
const dbUser = await controller.createUser(adminUser)
|
||||||
|
adminAccessToken = generateAccessToken({
|
||||||
|
clientId,
|
||||||
|
userId: dbUser.id
|
||||||
|
})
|
||||||
await saveTokensInDB(
|
await saveTokensInDB(
|
||||||
adminUser.username,
|
dbUser.id,
|
||||||
clientId,
|
clientId,
|
||||||
adminAccessToken,
|
adminAccessToken,
|
||||||
'refreshToken'
|
'refreshToken'
|
||||||
@@ -84,12 +85,12 @@ describe('user', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with Forbideen if access token is not of an admin account', async () => {
|
it('should respond with Forbideen if access token is not of an admin account', async () => {
|
||||||
|
const dbUser = await controller.createUser(user)
|
||||||
const accessToken = generateAccessToken({
|
const accessToken = generateAccessToken({
|
||||||
clientId,
|
clientId,
|
||||||
username: user.username
|
userId: dbUser.id
|
||||||
})
|
})
|
||||||
await controller.createUser(user)
|
await saveTokensInDB(dbUser.id, clientId, accessToken, 'refreshToken')
|
||||||
await saveTokensInDB(user.username, clientId, accessToken, 'refreshToken')
|
|
||||||
|
|
||||||
const res = await request(app)
|
const res = await request(app)
|
||||||
.post('/SASjsApi/user')
|
.post('/SASjsApi/user')
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
verifyAdmin,
|
verifyAdmin,
|
||||||
verifyAdminIfNeeded
|
verifyAdminIfNeeded
|
||||||
} from '../../middlewares'
|
} from '../../middlewares'
|
||||||
import User from '../../model/User'
|
|
||||||
import {
|
import {
|
||||||
deleteUserValidation,
|
deleteUserValidation,
|
||||||
registerUserValidation,
|
registerUserValidation,
|
||||||
@@ -39,13 +38,13 @@ userRouter.get('/', authenticateAccessToken, async (req, res) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// get one user
|
// get one user
|
||||||
userRouter.get('/:username', authenticateAccessToken, async (req: any, res) => {
|
userRouter.get('/:userId', authenticateAccessToken, async (req: any, res) => {
|
||||||
const { username } = req.params
|
const { userId } = req.params
|
||||||
|
|
||||||
|
const controller = new UserController()
|
||||||
try {
|
try {
|
||||||
const user = await User.findOne({ username })
|
const response = await controller.getUser(userId)
|
||||||
.select({ _id: 0, username: 1, displayName: 1, isAdmin: 1, isActive: 1 })
|
res.send(response)
|
||||||
.exec()
|
|
||||||
res.send(user)
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
res.status(403).send(err.toString())
|
res.status(403).send(err.toString())
|
||||||
}
|
}
|
||||||
@@ -53,12 +52,12 @@ userRouter.get('/:username', authenticateAccessToken, async (req: any, res) => {
|
|||||||
|
|
||||||
// update user
|
// update user
|
||||||
userRouter.patch(
|
userRouter.patch(
|
||||||
'/:username',
|
'/:userId',
|
||||||
authenticateAccessToken,
|
authenticateAccessToken,
|
||||||
verifyAdminIfNeeded,
|
verifyAdminIfNeeded,
|
||||||
async (req: any, res) => {
|
async (req: any, res) => {
|
||||||
const { user } = req
|
const { user } = req
|
||||||
const { username } = req.params
|
const { userId } = req.params
|
||||||
|
|
||||||
// only an admin can update `isActive` and `isAdmin` fields
|
// only an admin can update `isActive` and `isAdmin` fields
|
||||||
const { error, value: body } = updateUserValidation(req.body, user.isAdmin)
|
const { error, value: body } = updateUserValidation(req.body, user.isAdmin)
|
||||||
@@ -66,7 +65,7 @@ userRouter.patch(
|
|||||||
|
|
||||||
const controller = new UserController()
|
const controller = new UserController()
|
||||||
try {
|
try {
|
||||||
const response = await controller.updateUser(username, body)
|
const response = await controller.updateUser(userId, body)
|
||||||
res.send(response)
|
res.send(response)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
res.status(403).send(err.toString())
|
res.status(403).send(err.toString())
|
||||||
@@ -76,12 +75,12 @@ userRouter.patch(
|
|||||||
|
|
||||||
// delete user
|
// delete user
|
||||||
userRouter.delete(
|
userRouter.delete(
|
||||||
'/:username',
|
'/:userId',
|
||||||
authenticateAccessToken,
|
authenticateAccessToken,
|
||||||
verifyAdminIfNeeded,
|
verifyAdminIfNeeded,
|
||||||
async (req: any, res) => {
|
async (req: any, res) => {
|
||||||
const { user } = req
|
const { user } = req
|
||||||
const { username } = req.params
|
const { userId } = req.params
|
||||||
|
|
||||||
// only an admin can delete user without providing password
|
// only an admin can delete user without providing password
|
||||||
const { error, value: data } = deleteUserValidation(req.body, user.isAdmin)
|
const { error, value: data } = deleteUserValidation(req.body, user.isAdmin)
|
||||||
@@ -89,7 +88,7 @@ userRouter.delete(
|
|||||||
|
|
||||||
const controller = new UserController()
|
const controller = new UserController()
|
||||||
try {
|
try {
|
||||||
await controller.deleteUser(username, data, user.isAdmin)
|
await controller.deleteUser(userId, data, user.isAdmin)
|
||||||
res.status(200).send('Account Deleted!')
|
res.status(200).send('Account Deleted!')
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
res.status(403).send(err.toString())
|
res.status(403).send(err.toString())
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export interface InfoJWT {
|
export interface InfoJWT {
|
||||||
clientId: string
|
clientId: string
|
||||||
username: string
|
userId: number
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import User from '../model/User'
|
import User from '../model/User'
|
||||||
|
|
||||||
export const saveTokensInDB = async (
|
export const saveTokensInDB = async (
|
||||||
username: string,
|
userId: number,
|
||||||
clientId: string,
|
clientId: string,
|
||||||
accessToken: string,
|
accessToken: string,
|
||||||
refreshToken: string
|
refreshToken: string
|
||||||
) => {
|
) => {
|
||||||
const user = await User.findOne({ username })
|
const user = await User.findOne({ id: userId })
|
||||||
if (!user) return
|
if (!user) return
|
||||||
|
|
||||||
const currentTokenObj = user.tokens.find(
|
const currentTokenObj = user.tokens.find(
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import User from '../model/User'
|
import User from '../model/User'
|
||||||
|
|
||||||
export const verifyTokenInDB = async (
|
export const verifyTokenInDB = async (
|
||||||
username: string,
|
userId: number,
|
||||||
clientId: string,
|
clientId: string,
|
||||||
token: string,
|
token: string,
|
||||||
tokenType: 'accessToken' | 'refreshToken'
|
tokenType: 'accessToken' | 'refreshToken'
|
||||||
) => {
|
) => {
|
||||||
const dbUser = await User.findOne({ username })
|
const dbUser = await User.findOne({ id: userId })
|
||||||
|
|
||||||
if (!dbUser) return undefined
|
if (!dbUser) return undefined
|
||||||
|
|
||||||
@@ -16,8 +16,9 @@ export const verifyTokenInDB = async (
|
|||||||
|
|
||||||
return currentTokenObj?.[tokenType] === token
|
return currentTokenObj?.[tokenType] === token
|
||||||
? {
|
? {
|
||||||
|
userId: dbUser.id,
|
||||||
clientId,
|
clientId,
|
||||||
username,
|
username: dbUser.username,
|
||||||
isAdmin: dbUser.isAdmin,
|
isAdmin: dbUser.isAdmin,
|
||||||
isActive: dbUser.isActive
|
isActive: dbUser.isActive
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user