|
|
|
@ -325,7 +325,10 @@ export class User extends Model {
|
|
|
|
|
try {
|
|
|
|
|
const tfaToken = await WIKI.db.userKeys.generateToken({
|
|
|
|
|
kind: 'tfa',
|
|
|
|
|
userId: user.id
|
|
|
|
|
userId: user.id,
|
|
|
|
|
meta: {
|
|
|
|
|
strategyId
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return {
|
|
|
|
|
nextAction: 'provideTfa',
|
|
|
|
@ -341,7 +344,10 @@ export class User extends Model {
|
|
|
|
|
const tfaQRImage = await user.generateTFA(strategyId, siteId)
|
|
|
|
|
const tfaToken = await WIKI.db.userKeys.generateToken({
|
|
|
|
|
kind: 'tfaSetup',
|
|
|
|
|
userId: user.id
|
|
|
|
|
userId: user.id,
|
|
|
|
|
meta: {
|
|
|
|
|
strategyId
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return {
|
|
|
|
|
nextAction: 'setupTfa',
|
|
|
|
@ -361,7 +367,10 @@ export class User extends Model {
|
|
|
|
|
try {
|
|
|
|
|
const pwdChangeToken = await WIKI.db.userKeys.generateToken({
|
|
|
|
|
kind: 'changePwd',
|
|
|
|
|
userId: user.id
|
|
|
|
|
userId: user.id,
|
|
|
|
|
meta: {
|
|
|
|
|
strategyId
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
@ -435,11 +444,16 @@ export class User extends Model {
|
|
|
|
|
*/
|
|
|
|
|
static async loginTFA ({ strategyId, siteId, securityCode, continuationToken, setup }, context) {
|
|
|
|
|
if (securityCode.length === 6 && continuationToken.length > 1) {
|
|
|
|
|
const { user } = await WIKI.db.userKeys.validateToken({
|
|
|
|
|
const { user, strategyId: expectedStrategyId } = await WIKI.db.userKeys.validateToken({
|
|
|
|
|
kind: setup ? 'tfaSetup' : 'tfa',
|
|
|
|
|
token: continuationToken,
|
|
|
|
|
skipDelete: setup
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (strategyId !== expectedStrategyId) {
|
|
|
|
|
throw new Error('ERR_UNEXPECTED_STRATEGY_ID')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (user) {
|
|
|
|
|
if (user.verifyTFA(strategyId, securityCode)) {
|
|
|
|
|
if (setup) {
|
|
|
|
@ -447,40 +461,39 @@ export class User extends Model {
|
|
|
|
|
}
|
|
|
|
|
return WIKI.db.users.afterLoginChecks(user, strategyId, context, { siteId, skipTFA: true })
|
|
|
|
|
} else {
|
|
|
|
|
throw new WIKI.Error.AuthTFAFailed()
|
|
|
|
|
throw new Error('ERR_INCORRECT_TFA_TOKEN')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
throw new WIKI.Error.AuthTFAInvalid()
|
|
|
|
|
throw new Error('ERR_INVALID_TFA_REQUEST')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Change Password from a Mandatory Password Change after Login
|
|
|
|
|
*/
|
|
|
|
|
static async loginChangePassword ({ continuationToken, newPassword }, context) {
|
|
|
|
|
if (!newPassword || newPassword.length < 6) {
|
|
|
|
|
throw new WIKI.Error.InputInvalid('Password must be at least 6 characters!')
|
|
|
|
|
static async loginChangePassword ({ strategyId, siteId, continuationToken, newPassword }, context) {
|
|
|
|
|
if (!newPassword || newPassword.length < 8) {
|
|
|
|
|
throw new Error('ERR_PASSWORD_TOO_SHORT')
|
|
|
|
|
}
|
|
|
|
|
const usr = await WIKI.db.userKeys.validateToken({
|
|
|
|
|
const { user, strategyId: expectedStrategyId } = await WIKI.db.userKeys.validateToken({
|
|
|
|
|
kind: 'changePwd',
|
|
|
|
|
token: continuationToken
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (usr) {
|
|
|
|
|
await WIKI.db.users.query().patch({
|
|
|
|
|
password: newPassword,
|
|
|
|
|
mustChangePwd: false
|
|
|
|
|
}).findById(usr.id)
|
|
|
|
|
if (strategyId !== expectedStrategyId) {
|
|
|
|
|
throw new Error('ERR_UNEXPECTED_STRATEGY_ID')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
context.req.logIn(usr, { session: false }, async err => {
|
|
|
|
|
if (err) { return reject(err) }
|
|
|
|
|
const jwtToken = await WIKI.db.users.refreshToken(usr)
|
|
|
|
|
resolve({ jwt: jwtToken.token })
|
|
|
|
|
})
|
|
|
|
|
if (user) {
|
|
|
|
|
user.auth[strategyId].password = await bcrypt.hash(newPassword, 12),
|
|
|
|
|
user.auth[strategyId].mustChangePwd = false
|
|
|
|
|
await user.$query().patch({
|
|
|
|
|
auth: user.auth
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return WIKI.db.users.afterLoginChecks(user, strategyId, context, { siteId, skipChangePwd: true, skipTFA: true })
|
|
|
|
|
} else {
|
|
|
|
|
throw new WIKI.Error.UserNotFound()
|
|
|
|
|
throw new Error('ERR_INVALID_USER')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|