challenge validate session
This commit is contained in:
parent
a94f987519
commit
3d97f6659e
@ -25,6 +25,13 @@ import { UserService } from 'src/modules/objects/user/user.service';
|
|||||||
import { FormUtilityService } from 'src/modules/utility/services/form-utility.service';
|
import { FormUtilityService } from 'src/modules/utility/services/form-utility.service';
|
||||||
import { TokenService } from 'src/modules/utility/services/token.service';
|
import { TokenService } from 'src/modules/utility/services/token.service';
|
||||||
|
|
||||||
|
interface VerifyChallenge {
|
||||||
|
type: 'verify';
|
||||||
|
id: string;
|
||||||
|
user: string;
|
||||||
|
remember: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
@Controller('/login')
|
@Controller('/login')
|
||||||
export class LoginController {
|
export class LoginController {
|
||||||
constructor(
|
constructor(
|
||||||
@ -80,7 +87,12 @@ export class LoginController {
|
|||||||
await this.audit.auditRequest(req, AuditAction.LOGIN, req.session.id, user);
|
await this.audit.auditRequest(req, AuditAction.LOGIN, req.session.id, user);
|
||||||
|
|
||||||
if (await this.totpService.userHasTOTP(user)) {
|
if (await this.totpService.userHasTOTP(user)) {
|
||||||
const challenge = { type: 'verify', user: user.uuid, remember };
|
const challenge: VerifyChallenge = {
|
||||||
|
type: 'verify',
|
||||||
|
id: req.session.id,
|
||||||
|
user: user.uuid,
|
||||||
|
remember,
|
||||||
|
};
|
||||||
const encrypted = await this.token.encryptChallenge(challenge);
|
const encrypted = await this.token.encryptChallenge(challenge);
|
||||||
res.redirect(
|
res.redirect(
|
||||||
`login/verify?challenge=${encrypted}${
|
`login/verify?challenge=${encrypted}${
|
||||||
@ -141,12 +153,15 @@ export class LoginController {
|
|||||||
throw new Error('No challenge');
|
throw new Error('No challenge');
|
||||||
}
|
}
|
||||||
|
|
||||||
const decrypted = await this.token.decryptChallenge<{
|
const decrypted = await this.token.decryptChallenge<VerifyChallenge>(
|
||||||
type: 'verify';
|
query.challenge,
|
||||||
user: string;
|
);
|
||||||
remember: boolean;
|
if (
|
||||||
}>(query.challenge);
|
!decrypted ||
|
||||||
if (!decrypted || decrypted.type !== 'verify' || !decrypted.user) {
|
decrypted.type !== 'verify' ||
|
||||||
|
decrypted.id !== req.session.id ||
|
||||||
|
!decrypted.user
|
||||||
|
) {
|
||||||
throw new Error('Bad challenge');
|
throw new Error('Bad challenge');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import { QRCodeService } from 'src/modules/utility/services/qr-code.service';
|
|||||||
import { TokenService } from 'src/modules/utility/services/token.service';
|
import { TokenService } from 'src/modules/utility/services/token.service';
|
||||||
|
|
||||||
interface ChallengeType {
|
interface ChallengeType {
|
||||||
|
id: string;
|
||||||
secret: string;
|
secret: string;
|
||||||
type: 'totp';
|
type: 'totp';
|
||||||
user: string;
|
user: string;
|
||||||
@ -36,14 +37,23 @@ export class TwoFactorController {
|
|||||||
const challenge = await this.token.decryptChallenge<ChallengeType>(
|
const challenge = await this.token.decryptChallenge<ChallengeType>(
|
||||||
challengeString,
|
challengeString,
|
||||||
);
|
);
|
||||||
if (challenge.type === 'totp' && challenge.user === req.user.uuid) {
|
if (
|
||||||
|
challenge.type === 'totp' &&
|
||||||
|
challenge.user === req.user.uuid &&
|
||||||
|
challenge.id === req.session.id
|
||||||
|
) {
|
||||||
secret = challenge.secret;
|
secret = challenge.secret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!secret) {
|
if (!secret) {
|
||||||
secret = this.totp.createTOTPSecret();
|
secret = this.totp.createTOTPSecret();
|
||||||
const challenge = { type: 'totp', secret, user: req.user.uuid };
|
const challenge = {
|
||||||
|
type: 'totp',
|
||||||
|
secret,
|
||||||
|
id: req.session.id,
|
||||||
|
user: req.user.uuid,
|
||||||
|
};
|
||||||
const encrypted = await this.token.encryptChallenge(challenge);
|
const encrypted = await this.token.encryptChallenge(challenge);
|
||||||
const cleanURL = req.originalUrl.replace(/\?(.*)$/, '');
|
const cleanURL = req.originalUrl.replace(/\?(.*)$/, '');
|
||||||
res.redirect(`${cleanURL}?challenge=${encrypted}`);
|
res.redirect(`${cleanURL}?challenge=${encrypted}`);
|
||||||
@ -85,6 +95,7 @@ export class TwoFactorController {
|
|||||||
if (
|
if (
|
||||||
challenge.type !== 'totp' ||
|
challenge.type !== 'totp' ||
|
||||||
challenge.user !== req.user.uuid ||
|
challenge.user !== req.user.uuid ||
|
||||||
|
challenge.id !== req.session.id ||
|
||||||
!secret
|
!secret
|
||||||
) {
|
) {
|
||||||
throw new Error('Invalid request');
|
throw new Error('Invalid request');
|
||||||
|
Reference in New Issue
Block a user