@breadstone/archipel-platform-authentication 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/package.json +4 -3
- package/src/AuthModule.d.ts +17 -1
- package/src/AuthModule.js +32 -5
- package/src/connectors/AnonymousConnector.d.ts +1 -1
- package/src/connectors/AnonymousConnector.js +2 -2
- package/src/connectors/AppleConnector.d.ts +1 -1
- package/src/connectors/AppleConnector.js +2 -2
- package/src/connectors/GithubConnector.d.ts +1 -1
- package/src/connectors/GithubConnector.js +3 -2
- package/src/connectors/GoogleConnector.d.ts +1 -1
- package/src/connectors/GoogleConnector.js +2 -2
- package/src/connectors/JwtConnector.d.ts +1 -1
- package/src/connectors/JwtConnector.js +2 -2
- package/src/connectors/MicrosoftConnector.d.ts +1 -1
- package/src/connectors/MicrosoftConnector.js +2 -2
- package/src/connectors/apple/env.d.ts +1 -1
- package/src/connectors/github/env.d.ts +1 -1
- package/src/connectors/google/env.d.ts +1 -1
- package/src/connectors/microsoft/env.d.ts +1 -1
- package/src/contracts/ChallengeStorePort.d.ts +32 -0
- package/src/contracts/ChallengeStorePort.js +16 -0
- package/src/contracts/index.d.ts +1 -0
- package/src/contracts/index.js +3 -1
- package/src/env.d.ts +34 -34
- package/src/env.js +34 -34
- package/src/guards/index.js +0 -2
- package/src/mfa/MfaEncryptionService.d.ts +1 -1
- package/src/mfa/MfaEncryptionService.js +2 -2
- package/src/mfa/MfaService.js +0 -3
- package/src/mfa/channels/EmailOtpMfaChannel.d.ts +10 -1
- package/src/mfa/channels/EmailOtpMfaChannel.js +12 -2
- package/src/mfa/channels/PushMfaChannel.d.ts +8 -3
- package/src/mfa/channels/PushMfaChannel.js +10 -4
- package/src/mfa/channels/SmsMfaChannel.d.ts +10 -1
- package/src/mfa/channels/SmsMfaChannel.js +12 -2
- package/src/mfa/channels/TotpMfaChannel.d.ts +1 -1
- package/src/mfa/channels/TotpMfaChannel.js +2 -2
- package/src/services/ChallengeService.d.ts +7 -3
- package/src/services/ChallengeService.js +14 -9
- package/src/services/InMemoryChallengeStore.d.ts +16 -0
- package/src/services/InMemoryChallengeStore.js +40 -0
- package/src/services/SessionService.d.ts +8 -0
- package/src/services/SessionService.js +15 -0
- package/src/services/VerificationService.d.ts +10 -1
- package/src/services/VerificationService.js +31 -9
- package/src/strategies/AnonymousStrategy.d.ts +0 -32
- package/src/strategies/AnonymousStrategy.js +0 -54
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.VerificationService = void 0;
|
|
5
5
|
const tslib_1 = require("tslib");
|
|
6
|
+
const archipel_platform_configuration_1 = require("@breadstone/archipel-platform-configuration");
|
|
6
7
|
const archipel_platform_core_1 = require("@breadstone/archipel-platform-core");
|
|
7
8
|
const common_1 = require("@nestjs/common");
|
|
8
9
|
const jwt_1 = require("@nestjs/jwt");
|
|
10
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
11
|
const VerificationSubjectPort_1 = require("../contracts/VerificationSubjectPort");
|
|
10
12
|
const env_1 = require("../env");
|
|
11
13
|
// #endregion
|
|
@@ -65,6 +67,9 @@ let VerificationService = class VerificationService {
|
|
|
65
67
|
async verifyToken(token) {
|
|
66
68
|
if (this._jwtService.verify(token)) {
|
|
67
69
|
const jwt = this._jwtService.decode(token);
|
|
70
|
+
if (!jwt) {
|
|
71
|
+
throw new common_1.BadRequestException('Invalid or expired token');
|
|
72
|
+
}
|
|
68
73
|
// check if the token is expired
|
|
69
74
|
if (jwt.exp && Number(jwt.exp) < Math.floor(Date.now() / 1000)) {
|
|
70
75
|
throw new common_1.BadRequestException('Invalid or expired token');
|
|
@@ -87,19 +92,19 @@ let VerificationService = class VerificationService {
|
|
|
87
92
|
}
|
|
88
93
|
if (user.verificationToken) {
|
|
89
94
|
const jwt = await this.redeemToken(user.verificationToken);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
const jwtEmail = String(jwt['email'] ?? '');
|
|
96
|
+
const jwtPin = String(jwt['pin'] ?? '');
|
|
97
|
+
const userEmail = String(user.email ?? '');
|
|
98
|
+
const emailMatch = this.safeEqual(jwtEmail, userEmail);
|
|
99
|
+
const pinMatch = this.safeEqual(jwtPin, pin);
|
|
100
|
+
if (!emailMatch || !pinMatch) {
|
|
94
101
|
throw new common_1.BadRequestException('Invalid verification token');
|
|
95
102
|
}
|
|
96
103
|
if (jwt['exp'] && Number(jwt['exp']) < Math.floor(Date.now() / 1000)) {
|
|
97
104
|
throw new common_1.BadRequestException('Expired verification token');
|
|
98
105
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
106
|
+
await this._verificationSubject.markVerified(user.id);
|
|
107
|
+
return true;
|
|
103
108
|
}
|
|
104
109
|
return false;
|
|
105
110
|
}
|
|
@@ -113,6 +118,23 @@ let VerificationService = class VerificationService {
|
|
|
113
118
|
buildVerificationLink(token) {
|
|
114
119
|
return `${this._hostService.host}/api/auth/verify-token?token=${token}`; // get this dynamically or from config
|
|
115
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Performs a constant-time string comparison to prevent timing attacks.
|
|
123
|
+
*
|
|
124
|
+
* @param a - First string.
|
|
125
|
+
* @param b - Second string.
|
|
126
|
+
* @returns Whether the strings are equal.
|
|
127
|
+
*/
|
|
128
|
+
safeEqual(a, b) {
|
|
129
|
+
const bufA = Buffer.from(a, 'utf8');
|
|
130
|
+
const bufB = Buffer.from(b, 'utf8');
|
|
131
|
+
if (bufA.length !== bufB.length) {
|
|
132
|
+
// Perform a dummy comparison to keep constant time even on length mismatch
|
|
133
|
+
(0, node_crypto_1.timingSafeEqual)(bufA, bufA);
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
return (0, node_crypto_1.timingSafeEqual)(bufA, bufB);
|
|
137
|
+
}
|
|
116
138
|
};
|
|
117
139
|
exports.VerificationService = VerificationService;
|
|
118
140
|
exports.VerificationService = VerificationService = tslib_1.__decorate([
|
|
@@ -120,6 +142,6 @@ exports.VerificationService = VerificationService = tslib_1.__decorate([
|
|
|
120
142
|
tslib_1.__metadata("design:paramtypes", [jwt_1.JwtService,
|
|
121
143
|
archipel_platform_core_1.HostService,
|
|
122
144
|
VerificationSubjectPort_1.VerificationSubjectPort,
|
|
123
|
-
|
|
145
|
+
archipel_platform_configuration_1.ConfigService])
|
|
124
146
|
], VerificationService);
|
|
125
147
|
//# sourceMappingURL=VerificationService.js.map
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { ConfigService } from '@breadstone/archipel-platform-core';
|
|
2
|
-
import { Strategy } from 'passport-custom';
|
|
3
|
-
import { AuthSubjectPort } from '../contracts/AuthSubjectPort';
|
|
4
|
-
import type { IAuthSubject } from '../contracts/IAuthSubject';
|
|
5
|
-
declare const AnonymousStrategy_base: new () => Strategy & {
|
|
6
|
-
validate(...args: any[]): unknown;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Anonymous strategy for temporary user login.
|
|
10
|
-
*
|
|
11
|
-
* @public
|
|
12
|
-
*/
|
|
13
|
-
export declare class AnonymousStrategy extends AnonymousStrategy_base {
|
|
14
|
-
private readonly _authSubject;
|
|
15
|
-
private readonly _configService;
|
|
16
|
-
/**
|
|
17
|
-
* Constructs a new instance of the `AnonymousStrategy` class.
|
|
18
|
-
*
|
|
19
|
-
* @public
|
|
20
|
-
* @param authSubject Auth subject port instance.
|
|
21
|
-
* @param configService Configuration service instance.
|
|
22
|
-
*/
|
|
23
|
-
constructor(authSubject: AuthSubjectPort, configService: ConfigService);
|
|
24
|
-
/**
|
|
25
|
-
* Validates the authentication credentials.
|
|
26
|
-
*
|
|
27
|
-
* @public
|
|
28
|
-
* @returns The authenticated user and this is also later available in the request.user object
|
|
29
|
-
*/
|
|
30
|
-
validate(): Promise<IAuthSubject>;
|
|
31
|
-
}
|
|
32
|
-
export {};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// #region Imports
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.AnonymousStrategy = void 0;
|
|
5
|
-
const tslib_1 = require("tslib");
|
|
6
|
-
const archipel_platform_core_1 = require("@breadstone/archipel-platform-core");
|
|
7
|
-
const common_1 = require("@nestjs/common");
|
|
8
|
-
const passport_1 = require("@nestjs/passport");
|
|
9
|
-
const passport_custom_1 = require("passport-custom");
|
|
10
|
-
const AuthSubjectPort_1 = require("../contracts/AuthSubjectPort");
|
|
11
|
-
const env_1 = require("../env");
|
|
12
|
-
// #endregion
|
|
13
|
-
/**
|
|
14
|
-
* Anonymous strategy for temporary user login.
|
|
15
|
-
*
|
|
16
|
-
* @public
|
|
17
|
-
*/
|
|
18
|
-
let AnonymousStrategy = class AnonymousStrategy extends (0, passport_1.PassportStrategy)(passport_custom_1.Strategy, 'anonymous') {
|
|
19
|
-
// #endregion
|
|
20
|
-
// #region Ctor
|
|
21
|
-
/**
|
|
22
|
-
* Constructs a new instance of the `AnonymousStrategy` class.
|
|
23
|
-
*
|
|
24
|
-
* @public
|
|
25
|
-
* @param authSubject Auth subject port instance.
|
|
26
|
-
* @param configService Configuration service instance.
|
|
27
|
-
*/
|
|
28
|
-
constructor(authSubject, configService) {
|
|
29
|
-
super();
|
|
30
|
-
this._authSubject = authSubject;
|
|
31
|
-
this._configService = configService;
|
|
32
|
-
}
|
|
33
|
-
// #endregion
|
|
34
|
-
// #region Methods
|
|
35
|
-
/**
|
|
36
|
-
* Validates the authentication credentials.
|
|
37
|
-
*
|
|
38
|
-
* @public
|
|
39
|
-
* @returns The authenticated user and this is also later available in the request.user object
|
|
40
|
-
*/
|
|
41
|
-
async validate() {
|
|
42
|
-
const user = await this._authSubject.findAnonymous(this._configService.get(env_1.SEED_ANONYMOUS_USERNAME.key));
|
|
43
|
-
if (!user) {
|
|
44
|
-
throw new common_1.NotFoundException('User not found');
|
|
45
|
-
}
|
|
46
|
-
return user;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
exports.AnonymousStrategy = AnonymousStrategy;
|
|
50
|
-
exports.AnonymousStrategy = AnonymousStrategy = tslib_1.__decorate([
|
|
51
|
-
(0, common_1.Injectable)(),
|
|
52
|
-
tslib_1.__metadata("design:paramtypes", [AuthSubjectPort_1.AuthSubjectPort, archipel_platform_core_1.ConfigService])
|
|
53
|
-
], AnonymousStrategy);
|
|
54
|
-
//# sourceMappingURL=AnonymousStrategy.js.map
|