@breadstone/archipel-platform-authentication 0.0.1
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 +47 -0
- package/package.json +67 -0
- package/src/AuthModule.d.ts +57 -0
- package/src/AuthModule.js +158 -0
- package/src/contracts/AuthSubjectPort.d.ts +33 -0
- package/src/contracts/AuthSubjectPort.js +15 -0
- package/src/contracts/IAuthSubject.d.ts +40 -0
- package/src/contracts/IAuthSubject.js +3 -0
- package/src/contracts/IMfaSubject.d.ts +48 -0
- package/src/contracts/IMfaSubject.js +3 -0
- package/src/contracts/IMfaSubjectUpdate.d.ts +16 -0
- package/src/contracts/IMfaSubjectUpdate.js +3 -0
- package/src/contracts/ISessionRecord.d.ts +22 -0
- package/src/contracts/ISessionRecord.js +3 -0
- package/src/contracts/ISocialProfile.d.ts +23 -0
- package/src/contracts/ISocialProfile.js +3 -0
- package/src/contracts/IStoreSessionArgs.d.ts +14 -0
- package/src/contracts/IStoreSessionArgs.js +4 -0
- package/src/contracts/IVerifiableSubject.d.ts +28 -0
- package/src/contracts/IVerifiableSubject.js +3 -0
- package/src/contracts/MfaSubjectPort.d.ts +26 -0
- package/src/contracts/MfaSubjectPort.js +15 -0
- package/src/contracts/SessionPersistencePort.d.ts +58 -0
- package/src/contracts/SessionPersistencePort.js +15 -0
- package/src/contracts/SocialAuthPort.d.ts +19 -0
- package/src/contracts/SocialAuthPort.js +15 -0
- package/src/contracts/TokenEnricherPort.d.ts +17 -0
- package/src/contracts/TokenEnricherPort.js +15 -0
- package/src/contracts/VerificationSubjectPort.d.ts +40 -0
- package/src/contracts/VerificationSubjectPort.js +15 -0
- package/src/contracts/index.d.ts +13 -0
- package/src/contracts/index.js +16 -0
- package/src/decorators/RolesDecorator.d.ts +12 -0
- package/src/decorators/RolesDecorator.js +23 -0
- package/src/decorators/TokenDecorator.d.ts +6 -0
- package/src/decorators/TokenDecorator.js +20 -0
- package/src/decorators/UserDecorator.d.ts +6 -0
- package/src/decorators/UserDecorator.js +16 -0
- package/src/decorators/index.d.ts +3 -0
- package/src/decorators/index.js +7 -0
- package/src/env.d.ts +57 -0
- package/src/env.js +179 -0
- package/src/guards/AnonymousAuthGuard.d.ts +9 -0
- package/src/guards/AnonymousAuthGuard.js +20 -0
- package/src/guards/GithubAuthGuard.d.ts +9 -0
- package/src/guards/GithubAuthGuard.js +20 -0
- package/src/guards/JwtAuthGuard.d.ts +9 -0
- package/src/guards/JwtAuthGuard.js +20 -0
- package/src/guards/LocalAuthGuard.d.ts +9 -0
- package/src/guards/LocalAuthGuard.js +20 -0
- package/src/guards/RolesGuard.d.ts +16 -0
- package/src/guards/RolesGuard.js +43 -0
- package/src/guards/SocialAuthGuard.d.ts +9 -0
- package/src/guards/SocialAuthGuard.js +35 -0
- package/src/guards/_RefreshTokenAuthGuard.d.ts +0 -0
- package/src/guards/_RefreshTokenAuthGuard.js +2 -0
- package/src/guards/_TwoFactorAuthGuard.d.ts +0 -0
- package/src/guards/_TwoFactorAuthGuard.js +2 -0
- package/src/guards/index.d.ts +6 -0
- package/src/guards/index.js +12 -0
- package/src/index.d.ts +9 -0
- package/src/index.js +13 -0
- package/src/mappers/SessionMappingProfile.d.ts +42 -0
- package/src/mappers/SessionMappingProfile.js +68 -0
- package/src/middlewares/LastActiveMiddleware.d.ts +29 -0
- package/src/middlewares/LastActiveMiddleware.js +55 -0
- package/src/middlewares/index.d.ts +1 -0
- package/src/middlewares/index.js +5 -0
- package/src/models/IMfaChallengePayload.d.ts +31 -0
- package/src/models/IMfaChallengePayload.js +3 -0
- package/src/models/IMfaConfirmation.d.ts +11 -0
- package/src/models/IMfaConfirmation.js +3 -0
- package/src/models/IMfaSetup.d.ts +23 -0
- package/src/models/IMfaSetup.js +3 -0
- package/src/models/ISignInResult.d.ts +31 -0
- package/src/models/ISignInResult.js +3 -0
- package/src/models/JwtPayloadBase.d.ts +44 -0
- package/src/models/JwtPayloadBase.js +55 -0
- package/src/models/index.d.ts +6 -0
- package/src/models/index.js +10 -0
- package/src/models/responses/SessionResponse.d.ts +20 -0
- package/src/models/responses/SessionResponse.js +164 -0
- package/src/models/responses/index.d.ts +1 -0
- package/src/models/responses/index.js +5 -0
- package/src/serializer/SessionSerializer.d.ts +5 -0
- package/src/serializer/SessionSerializer.js +23 -0
- package/src/services/AuthTokenService.d.ts +30 -0
- package/src/services/AuthTokenService.js +58 -0
- package/src/services/ChallengeService.d.ts +41 -0
- package/src/services/ChallengeService.js +89 -0
- package/src/services/MfaService.d.ts +60 -0
- package/src/services/MfaService.js +251 -0
- package/src/services/SessionService.d.ts +66 -0
- package/src/services/SessionService.js +108 -0
- package/src/services/VerificationService.d.ts +56 -0
- package/src/services/VerificationService.js +124 -0
- package/src/services/index.d.ts +5 -0
- package/src/services/index.js +9 -0
- package/src/services/mfa/IMfaChannel.d.ts +40 -0
- package/src/services/mfa/IMfaChannel.js +4 -0
- package/src/services/mfa/MfaEncryptionService.d.ts +23 -0
- package/src/services/mfa/MfaEncryptionService.js +59 -0
- package/src/services/mfa/MfaState.d.ts +38 -0
- package/src/services/mfa/MfaState.js +23 -0
- package/src/services/mfa/MfaTokens.d.ts +4 -0
- package/src/services/mfa/MfaTokens.js +8 -0
- package/src/services/mfa/channels/EmailOtpMfaChannel.d.ts +21 -0
- package/src/services/mfa/channels/EmailOtpMfaChannel.js +152 -0
- package/src/services/mfa/channels/PushMfaChannel.d.ts +25 -0
- package/src/services/mfa/channels/PushMfaChannel.js +150 -0
- package/src/services/mfa/channels/SmsMfaChannel.d.ts +21 -0
- package/src/services/mfa/channels/SmsMfaChannel.js +158 -0
- package/src/services/mfa/channels/TotpMfaChannel.d.ts +19 -0
- package/src/services/mfa/channels/TotpMfaChannel.js +100 -0
- package/src/strategies/AnonymousStrategy.d.ts +32 -0
- package/src/strategies/AnonymousStrategy.js +53 -0
- package/src/strategies/AppleStrategy.d.ts +38 -0
- package/src/strategies/AppleStrategy.js +79 -0
- package/src/strategies/GithubStrategy.d.ts +24 -0
- package/src/strategies/GithubStrategy.js +65 -0
- package/src/strategies/GoogleStrategy.d.ts +34 -0
- package/src/strategies/GoogleStrategy.js +74 -0
- package/src/strategies/JwtStrategy.d.ts +31 -0
- package/src/strategies/JwtStrategy.js +55 -0
- package/src/strategies/LocalStrategy.d.ts +31 -0
- package/src/strategies/LocalStrategy.js +56 -0
- package/src/strategies/MicrosoftStrategy.d.ts +35 -0
- package/src/strategies/MicrosoftStrategy.js +75 -0
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @breadstone/archipel-platform-authentication
|
|
2
|
+
|
|
3
|
+
Authentication and authorization infrastructure for NestJS applications.
|
|
4
|
+
|
|
5
|
+
## ⚠️ Environment Variables (Most Important)
|
|
6
|
+
|
|
7
|
+
| Variable | Required | Default |
|
|
8
|
+
| ------------------------------ | -------- | ------- |
|
|
9
|
+
| `AUTH_JWT_SECRET` | yes | - |
|
|
10
|
+
| `AUTH_JWT_EXPIRES_IN` | yes | - |
|
|
11
|
+
| `AUTH_VERIFY_JWT_EXPIRES_IN` | yes | - |
|
|
12
|
+
| `AUTH_GOOGLE_CLIENT_ID` | yes | - |
|
|
13
|
+
| `AUTH_GOOGLE_CLIENT_SECRET` | yes | - |
|
|
14
|
+
| `AUTH_MICROSOFT_CLIENT_ID` | yes | - |
|
|
15
|
+
| `AUTH_MICROSOFT_CLIENT_SECRET` | yes | - |
|
|
16
|
+
| `AUTH_APPLE_PRIVATE_KEY` | yes | - |
|
|
17
|
+
| `AUTH_APPLE_CLIENT_ID` | yes | - |
|
|
18
|
+
| `AUTH_APPLE_TEAM_ID` | yes | - |
|
|
19
|
+
| `AUTH_APPLE_KEY_ID` | yes | - |
|
|
20
|
+
| `AUTH_GITHUB_CLIENT_ID` | yes | - |
|
|
21
|
+
| `AUTH_GITHUB_CLIENT_SECRET` | yes | - |
|
|
22
|
+
| `SEED_ANONYMOUS_USERNAME` | yes | - |
|
|
23
|
+
|
|
24
|
+
For the full list (including MFA/OAuth callback defaults), see [`../../ENVIRONMENT_VARIABLES.md`](../../ENVIRONMENT_VARIABLES.md).
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { AuthModule } from '@breadstone/archipel-platform-authentication';
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Documentation
|
|
33
|
+
|
|
34
|
+
📖 **Auth Module:** [`docs/backend/modules/auth.md`](../../../docs/backend/modules/auth.md)
|
|
35
|
+
|
|
36
|
+
## Development
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Build
|
|
40
|
+
yarn nx build platform-authentication
|
|
41
|
+
|
|
42
|
+
# Test
|
|
43
|
+
yarn nx test platform-authentication
|
|
44
|
+
|
|
45
|
+
# Lint
|
|
46
|
+
yarn nx lint platform-authentication
|
|
47
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@breadstone/archipel-platform-authentication",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "JWT and OAuth authentication, MFA, session management, and email verification for NestJS applications.",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"types": "./src/index.d.ts",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/RueDeRennes/archipel",
|
|
12
|
+
"directory": "libs/platform-authentication"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"nestjs",
|
|
16
|
+
"authentication",
|
|
17
|
+
"jwt",
|
|
18
|
+
"oauth",
|
|
19
|
+
"mfa",
|
|
20
|
+
"passport",
|
|
21
|
+
"session",
|
|
22
|
+
"archipel"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"src/**/*.js",
|
|
29
|
+
"src/**/*.d.ts",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@breadstone/archipel-platform-core": "0.0.1",
|
|
34
|
+
"@breadstone/archipel-platform-database": "0.0.1",
|
|
35
|
+
"@breadstone/archipel-platform-mailing": "0.0.1",
|
|
36
|
+
"@breadstone/archipel-platform-openapi": "0.0.1",
|
|
37
|
+
"@nestjs/common": "11.1.18",
|
|
38
|
+
"@nestjs/core": "11.1.18",
|
|
39
|
+
"@nestjs/jwt": "11.0.2",
|
|
40
|
+
"@nestjs/passport": "11.0.5",
|
|
41
|
+
"@nestjs/swagger": "11.2.6",
|
|
42
|
+
"bcrypt": "6.0.0",
|
|
43
|
+
"class-transformer": "0.5.1",
|
|
44
|
+
"class-validator": "0.15.1",
|
|
45
|
+
"express": "5.2.1",
|
|
46
|
+
"passport": "0.7.0",
|
|
47
|
+
"passport-apple": "2.0.2",
|
|
48
|
+
"passport-custom": "1.1.1",
|
|
49
|
+
"passport-github2": "0.1.12",
|
|
50
|
+
"passport-google-oauth20": "2.0.0",
|
|
51
|
+
"passport-jwt": "4.0.1",
|
|
52
|
+
"passport-local": "1.0.0",
|
|
53
|
+
"passport-microsoft": "2.1.0",
|
|
54
|
+
"rxjs": "7.8.2",
|
|
55
|
+
"tslib": "2.8.1"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/passport-apple": "2.0.3",
|
|
59
|
+
"@types/passport-github2": "1.2.9",
|
|
60
|
+
"@types/passport-google-oauth20": "2.0.17",
|
|
61
|
+
"@types/passport-jwt": "4.0.1",
|
|
62
|
+
"@types/passport-local": "1.0.38",
|
|
63
|
+
"@types/passport-microsoft": "2.1.1",
|
|
64
|
+
"@types/qrcode": "1.5.6",
|
|
65
|
+
"vitest": "4.1.2"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DynamicModule, MiddlewareConsumer, Type } from '@nestjs/common';
|
|
2
|
+
import { AuthSubjectPort } from './contracts/AuthSubjectPort';
|
|
3
|
+
import { MfaSubjectPort } from './contracts/MfaSubjectPort';
|
|
4
|
+
import { SessionPersistencePort } from './contracts/SessionPersistencePort';
|
|
5
|
+
import { SocialAuthPort } from './contracts/SocialAuthPort';
|
|
6
|
+
import { TokenEnricherPort } from './contracts/TokenEnricherPort';
|
|
7
|
+
import { VerificationSubjectPort } from './contracts/VerificationSubjectPort';
|
|
8
|
+
/**
|
|
9
|
+
* Options for configuring the `AuthModule`.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export interface IAuthModuleOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Implementation of the auth subject port (user lookup for JWT/Local/Anonymous strategies).
|
|
16
|
+
*/
|
|
17
|
+
authSubject: Type<AuthSubjectPort>;
|
|
18
|
+
/**
|
|
19
|
+
* Implementation of the MFA subject port (MFA state persistence).
|
|
20
|
+
*/
|
|
21
|
+
mfaSubject: Type<MfaSubjectPort>;
|
|
22
|
+
/**
|
|
23
|
+
* Implementation of the session persistence port.
|
|
24
|
+
*/
|
|
25
|
+
sessionPersistence: Type<SessionPersistencePort>;
|
|
26
|
+
/**
|
|
27
|
+
* Implementation of the verification subject port (email/pin verification).
|
|
28
|
+
*/
|
|
29
|
+
verificationSubject: Type<VerificationSubjectPort>;
|
|
30
|
+
/**
|
|
31
|
+
* Optional implementation of the social auth port (OAuth strategies).
|
|
32
|
+
* When provided, social strategies (GitHub, Google, Microsoft, Apple) are registered.
|
|
33
|
+
*/
|
|
34
|
+
socialAuth?: Type<SocialAuthPort>;
|
|
35
|
+
/**
|
|
36
|
+
* Optional implementation of the token enricher port.
|
|
37
|
+
* When provided, additional claims are added to JWT tokens.
|
|
38
|
+
*/
|
|
39
|
+
tokenEnricher?: Type<TokenEnricherPort>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The `AuthModule` handles JWT-based authentication,
|
|
43
|
+
* including token creation and validation.
|
|
44
|
+
*
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
export declare class AuthModule {
|
|
48
|
+
/**
|
|
49
|
+
* Registers the auth module with the provided port implementations.
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
* @param options - Port implementations for the auth module.
|
|
53
|
+
* @returns The configured dynamic module.
|
|
54
|
+
*/
|
|
55
|
+
static register(options: IAuthModuleOptions): DynamicModule;
|
|
56
|
+
configure(consumer: MiddlewareConsumer): void;
|
|
57
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// #region Imports
|
|
3
|
+
var AuthModule_1;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.AuthModule = void 0;
|
|
6
|
+
const tslib_1 = require("tslib");
|
|
7
|
+
const archipel_platform_core_1 = require("@breadstone/archipel-platform-core");
|
|
8
|
+
const common_1 = require("@nestjs/common");
|
|
9
|
+
const jwt_1 = require("@nestjs/jwt");
|
|
10
|
+
const passport_1 = require("@nestjs/passport");
|
|
11
|
+
const AuthSubjectPort_1 = require("./contracts/AuthSubjectPort");
|
|
12
|
+
const MfaSubjectPort_1 = require("./contracts/MfaSubjectPort");
|
|
13
|
+
const SessionPersistencePort_1 = require("./contracts/SessionPersistencePort");
|
|
14
|
+
const SocialAuthPort_1 = require("./contracts/SocialAuthPort");
|
|
15
|
+
const TokenEnricherPort_1 = require("./contracts/TokenEnricherPort");
|
|
16
|
+
const VerificationSubjectPort_1 = require("./contracts/VerificationSubjectPort");
|
|
17
|
+
const env_1 = require("./env");
|
|
18
|
+
const AnonymousAuthGuard_1 = require("./guards/AnonymousAuthGuard");
|
|
19
|
+
const GithubAuthGuard_1 = require("./guards/GithubAuthGuard");
|
|
20
|
+
const JwtAuthGuard_1 = require("./guards/JwtAuthGuard");
|
|
21
|
+
const LocalAuthGuard_1 = require("./guards/LocalAuthGuard");
|
|
22
|
+
const RolesGuard_1 = require("./guards/RolesGuard");
|
|
23
|
+
const SessionMappingProfile_1 = require("./mappers/SessionMappingProfile");
|
|
24
|
+
const middlewares_1 = require("./middlewares");
|
|
25
|
+
const SessionSerializer_1 = require("./serializer/SessionSerializer");
|
|
26
|
+
const AuthTokenService_1 = require("./services/AuthTokenService");
|
|
27
|
+
const ChallengeService_1 = require("./services/ChallengeService");
|
|
28
|
+
const EmailOtpMfaChannel_1 = require("./services/mfa/channels/EmailOtpMfaChannel");
|
|
29
|
+
const PushMfaChannel_1 = require("./services/mfa/channels/PushMfaChannel");
|
|
30
|
+
const SmsMfaChannel_1 = require("./services/mfa/channels/SmsMfaChannel");
|
|
31
|
+
const TotpMfaChannel_1 = require("./services/mfa/channels/TotpMfaChannel");
|
|
32
|
+
const MfaEncryptionService_1 = require("./services/mfa/MfaEncryptionService");
|
|
33
|
+
const MfaTokens_1 = require("./services/mfa/MfaTokens");
|
|
34
|
+
const MfaService_1 = require("./services/MfaService");
|
|
35
|
+
const SessionService_1 = require("./services/SessionService");
|
|
36
|
+
const VerificationService_1 = require("./services/VerificationService");
|
|
37
|
+
const AnonymousStrategy_1 = require("./strategies/AnonymousStrategy");
|
|
38
|
+
const AppleStrategy_1 = require("./strategies/AppleStrategy");
|
|
39
|
+
const GithubStrategy_1 = require("./strategies/GithubStrategy");
|
|
40
|
+
const GoogleStrategy_1 = require("./strategies/GoogleStrategy");
|
|
41
|
+
const JwtStrategy_1 = require("./strategies/JwtStrategy");
|
|
42
|
+
const LocalStrategy_1 = require("./strategies/LocalStrategy");
|
|
43
|
+
const MicrosoftStrategy_1 = require("./strategies/MicrosoftStrategy");
|
|
44
|
+
/**
|
|
45
|
+
* The `AuthModule` handles JWT-based authentication,
|
|
46
|
+
* including token creation and validation.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
let AuthModule = AuthModule_1 = class AuthModule {
|
|
51
|
+
// #region Methods
|
|
52
|
+
/**
|
|
53
|
+
* Registers the auth module with the provided port implementations.
|
|
54
|
+
*
|
|
55
|
+
* @public
|
|
56
|
+
* @param options - Port implementations for the auth module.
|
|
57
|
+
* @returns The configured dynamic module.
|
|
58
|
+
*/
|
|
59
|
+
static register(options) {
|
|
60
|
+
const portProviders = [
|
|
61
|
+
{ provide: AuthSubjectPort_1.AuthSubjectPort, useClass: options.authSubject },
|
|
62
|
+
{ provide: MfaSubjectPort_1.MfaSubjectPort, useClass: options.mfaSubject },
|
|
63
|
+
{ provide: SessionPersistencePort_1.SessionPersistencePort, useClass: options.sessionPersistence },
|
|
64
|
+
{ provide: VerificationSubjectPort_1.VerificationSubjectPort, useClass: options.verificationSubject },
|
|
65
|
+
];
|
|
66
|
+
if (options.socialAuth) {
|
|
67
|
+
portProviders.push({ provide: SocialAuthPort_1.SocialAuthPort, useClass: options.socialAuth });
|
|
68
|
+
}
|
|
69
|
+
if (options.tokenEnricher) {
|
|
70
|
+
portProviders.push({ provide: TokenEnricherPort_1.TokenEnricherPort, useClass: options.tokenEnricher });
|
|
71
|
+
}
|
|
72
|
+
const strategies = [JwtStrategy_1.JwtStrategy, LocalStrategy_1.LocalStrategy, AnonymousStrategy_1.AnonymousStrategy];
|
|
73
|
+
if (options.socialAuth) {
|
|
74
|
+
strategies.push(GithubStrategy_1.GithubStrategy, GoogleStrategy_1.GoogleStrategy, MicrosoftStrategy_1.MicrosoftStrategy, AppleStrategy_1.AppleStrategy);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
module: AuthModule_1,
|
|
78
|
+
imports: [
|
|
79
|
+
archipel_platform_core_1.ConfigModule.register('platform-authentication', env_1.PLATFORM_AUTHENTICATION_CONFIG_ENTRIES),
|
|
80
|
+
archipel_platform_core_1.EventModule,
|
|
81
|
+
archipel_platform_core_1.IdentifierModule,
|
|
82
|
+
passport_1.PassportModule.register({
|
|
83
|
+
defaultStrategy: 'jwt',
|
|
84
|
+
session: true,
|
|
85
|
+
}),
|
|
86
|
+
jwt_1.JwtModule.register({
|
|
87
|
+
secret: process.env['AUTH_JWT_SECRET'],
|
|
88
|
+
signOptions: {
|
|
89
|
+
expiresIn: archipel_platform_core_1.DateTimeUtils.parse(process.env['AUTH_JWT_EXPIRES_IN']),
|
|
90
|
+
},
|
|
91
|
+
}),
|
|
92
|
+
archipel_platform_core_1.MappingModule.withProfiles([SessionMappingProfile_1.SessionMappingProfile]),
|
|
93
|
+
],
|
|
94
|
+
providers: [
|
|
95
|
+
...portProviders,
|
|
96
|
+
...strategies,
|
|
97
|
+
SessionSerializer_1.SessionSerializer,
|
|
98
|
+
JwtAuthGuard_1.JwtAuthGuard,
|
|
99
|
+
LocalAuthGuard_1.LocalAuthGuard,
|
|
100
|
+
AnonymousAuthGuard_1.AnonymousAuthGuard,
|
|
101
|
+
GithubAuthGuard_1.GithubAuthGuard,
|
|
102
|
+
RolesGuard_1.RolesGuard,
|
|
103
|
+
AuthTokenService_1.AuthTokenService,
|
|
104
|
+
VerificationService_1.VerificationService,
|
|
105
|
+
SessionService_1.SessionService,
|
|
106
|
+
MfaService_1.MfaService,
|
|
107
|
+
ChallengeService_1.ChallengeService,
|
|
108
|
+
TotpMfaChannel_1.TotpMfaChannel,
|
|
109
|
+
SmsMfaChannel_1.SmsMfaChannel,
|
|
110
|
+
EmailOtpMfaChannel_1.EmailOtpMfaChannel,
|
|
111
|
+
PushMfaChannel_1.PushMfaChannel,
|
|
112
|
+
MfaEncryptionService_1.MfaEncryptionService,
|
|
113
|
+
{
|
|
114
|
+
provide: archipel_platform_core_1.OTP_SERVICE_TOKEN,
|
|
115
|
+
useClass: archipel_platform_core_1.OtpService,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
provide: MfaTokens_1.MFA_CHANNELS,
|
|
119
|
+
useFactory: (totpChannel, smsChannel, emailChannel, pushChannel) => [totpChannel, smsChannel, emailChannel, pushChannel],
|
|
120
|
+
inject: [TotpMfaChannel_1.TotpMfaChannel, SmsMfaChannel_1.SmsMfaChannel, EmailOtpMfaChannel_1.EmailOtpMfaChannel, PushMfaChannel_1.PushMfaChannel],
|
|
121
|
+
},
|
|
122
|
+
archipel_platform_core_1.DeviceParserService,
|
|
123
|
+
middlewares_1.LastActiveMiddleware,
|
|
124
|
+
archipel_platform_core_1.BcryptService,
|
|
125
|
+
archipel_platform_core_1.CryptoService,
|
|
126
|
+
archipel_platform_core_1.HostService,
|
|
127
|
+
],
|
|
128
|
+
exports: [
|
|
129
|
+
AuthTokenService_1.AuthTokenService,
|
|
130
|
+
VerificationService_1.VerificationService,
|
|
131
|
+
SessionService_1.SessionService,
|
|
132
|
+
MfaService_1.MfaService,
|
|
133
|
+
ChallengeService_1.ChallengeService,
|
|
134
|
+
JwtAuthGuard_1.JwtAuthGuard,
|
|
135
|
+
LocalAuthGuard_1.LocalAuthGuard,
|
|
136
|
+
AnonymousAuthGuard_1.AnonymousAuthGuard,
|
|
137
|
+
GithubAuthGuard_1.GithubAuthGuard,
|
|
138
|
+
RolesGuard_1.RolesGuard,
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
configure(consumer) {
|
|
143
|
+
consumer.apply(archipel_platform_core_1.LimitRequestSizeMiddleware).forRoutes({
|
|
144
|
+
path: 'api/auth/register',
|
|
145
|
+
method: common_1.RequestMethod.POST,
|
|
146
|
+
});
|
|
147
|
+
consumer.apply(middlewares_1.LastActiveMiddleware).forRoutes({
|
|
148
|
+
path: '*',
|
|
149
|
+
method: common_1.RequestMethod.ALL,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
exports.AuthModule = AuthModule;
|
|
154
|
+
exports.AuthModule = AuthModule = AuthModule_1 = tslib_1.__decorate([
|
|
155
|
+
(0, common_1.Global)(),
|
|
156
|
+
(0, common_1.Module)({})
|
|
157
|
+
], AuthModule);
|
|
158
|
+
//# sourceMappingURL=AuthModule.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IAuthSubject } from './IAuthSubject';
|
|
2
|
+
/**
|
|
3
|
+
* Abstract port for resolving authentication subjects by identity.
|
|
4
|
+
* Used by the JWT, Local, and Anonymous strategies.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class AuthSubjectPort {
|
|
9
|
+
/**
|
|
10
|
+
* Find a subject by its unique identifier.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
* @param id - The subject identifier.
|
|
14
|
+
* @returns The subject or `null`.
|
|
15
|
+
*/
|
|
16
|
+
abstract findById(id: string): Promise<IAuthSubject | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Find a subject by its login name (user name or email).
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
* @param login - The login identifier.
|
|
22
|
+
* @returns The subject or `null`.
|
|
23
|
+
*/
|
|
24
|
+
abstract findByLogin(login: string): Promise<IAuthSubject | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Find the anonymous / seed subject by user name.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
* @param userName - The anonymous user name.
|
|
30
|
+
* @returns The subject or `null`.
|
|
31
|
+
*/
|
|
32
|
+
abstract findAnonymous(userName: string): Promise<IAuthSubject | null>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// #region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.AuthSubjectPort = void 0;
|
|
5
|
+
// #endregion
|
|
6
|
+
/**
|
|
7
|
+
* Abstract port for resolving authentication subjects by identity.
|
|
8
|
+
* Used by the JWT, Local, and Anonymous strategies.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
class AuthSubjectPort {
|
|
13
|
+
}
|
|
14
|
+
exports.AuthSubjectPort = AuthSubjectPort;
|
|
15
|
+
//# sourceMappingURL=AuthSubjectPort.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic authentication subject returned by the {@link AuthSubjectPort}.
|
|
3
|
+
* Represents any entity that can authenticate (user, service account, etc.).
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface IAuthSubject {
|
|
8
|
+
/**
|
|
9
|
+
* Unique identifier.
|
|
10
|
+
*/
|
|
11
|
+
readonly id: string;
|
|
12
|
+
/**
|
|
13
|
+
* Login name (user name, email alias, etc.).
|
|
14
|
+
*/
|
|
15
|
+
readonly userName: string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Email address.
|
|
18
|
+
*/
|
|
19
|
+
readonly email: string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Hashed password. `null` for social-only accounts.
|
|
22
|
+
*/
|
|
23
|
+
readonly password: string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the account has been verified (e.g. email confirmation).
|
|
26
|
+
*/
|
|
27
|
+
readonly isVerified: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Whether the account is anonymous.
|
|
30
|
+
*/
|
|
31
|
+
readonly isAnonymous: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Assigned role strings (e.g. `['user', 'admin']`).
|
|
34
|
+
*/
|
|
35
|
+
readonly roles: ReadonlyArray<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether MFA is enabled for this subject.
|
|
38
|
+
*/
|
|
39
|
+
readonly mfaEnabled: boolean;
|
|
40
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents an MFA-enabled subject. Contains the data the MFA subsystem
|
|
3
|
+
* needs to read and write MFA state on the underlying user-like entity.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface IMfaSubject {
|
|
8
|
+
/**
|
|
9
|
+
* Unique identifier.
|
|
10
|
+
*/
|
|
11
|
+
readonly id: string;
|
|
12
|
+
/**
|
|
13
|
+
* Email address, used by the email OTP channel.
|
|
14
|
+
*/
|
|
15
|
+
readonly email: string | null;
|
|
16
|
+
/**
|
|
17
|
+
* User name, used as TOTP account label.
|
|
18
|
+
*/
|
|
19
|
+
readonly userName: string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Whether MFA is currently enabled.
|
|
22
|
+
*/
|
|
23
|
+
readonly mfaEnabled: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Legacy TOTP secret (plain text). Used for migration to channel-based state.
|
|
26
|
+
*/
|
|
27
|
+
readonly mfaSecret: string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Hashed backup codes.
|
|
30
|
+
*/
|
|
31
|
+
readonly mfaBackupCodes: ReadonlyArray<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Preferred MFA method.
|
|
34
|
+
*/
|
|
35
|
+
readonly mfaPreferredMethod: string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Last time MFA was verified.
|
|
38
|
+
*/
|
|
39
|
+
readonly mfaVerifiedAt: Date | null;
|
|
40
|
+
/**
|
|
41
|
+
* Serialized per-channel MFA state (JSON object).
|
|
42
|
+
*/
|
|
43
|
+
readonly mfaChannels: unknown;
|
|
44
|
+
/**
|
|
45
|
+
* Phone number, used by the SMS channel.
|
|
46
|
+
*/
|
|
47
|
+
readonly phoneNumber: string | null;
|
|
48
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data payload for updating MFA state on the underlying entity.
|
|
3
|
+
* All properties are optional — only the provided ones are applied.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface IMfaSubjectUpdate {
|
|
8
|
+
readonly mfaEnabled?: boolean;
|
|
9
|
+
readonly mfaSecret?: string | null;
|
|
10
|
+
readonly mfaBackupCodes?: string[];
|
|
11
|
+
readonly mfaPreferredMethod?: string | null;
|
|
12
|
+
readonly mfaVerifiedAt?: Date | null;
|
|
13
|
+
readonly mfaUpdatedAt?: Date;
|
|
14
|
+
readonly mfaChannels?: unknown;
|
|
15
|
+
readonly phoneNumber?: string;
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a persisted session record.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface ISessionRecord {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly token: string;
|
|
9
|
+
readonly userId: string;
|
|
10
|
+
readonly ipAddress: string;
|
|
11
|
+
readonly userAgent: string | null;
|
|
12
|
+
readonly deviceType: string | null;
|
|
13
|
+
readonly deviceName: string | null;
|
|
14
|
+
readonly browserName: string | null;
|
|
15
|
+
readonly browserVersion: string | null;
|
|
16
|
+
readonly osName: string | null;
|
|
17
|
+
readonly osVersion: string | null;
|
|
18
|
+
readonly location: string | null;
|
|
19
|
+
readonly clientName: string | null;
|
|
20
|
+
readonly lastActive: Date;
|
|
21
|
+
readonly createdAt: Date;
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile data received from a social / OAuth provider.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface ISocialProfile {
|
|
7
|
+
/**
|
|
8
|
+
* The OAuth provider name (e.g. 'github', 'google', 'microsoft', 'apple').
|
|
9
|
+
*/
|
|
10
|
+
readonly provider: string;
|
|
11
|
+
/**
|
|
12
|
+
* User name as reported by the provider.
|
|
13
|
+
*/
|
|
14
|
+
readonly userName: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Email address as reported by the provider.
|
|
17
|
+
*/
|
|
18
|
+
readonly email: string;
|
|
19
|
+
/**
|
|
20
|
+
* Display name.
|
|
21
|
+
*/
|
|
22
|
+
readonly displayName: string | null;
|
|
23
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IDeviceInfo } from '@breadstone/archipel-platform-core';
|
|
2
|
+
/**
|
|
3
|
+
* Arguments for storing a new session.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface IStoreSessionArgs {
|
|
8
|
+
readonly token: string;
|
|
9
|
+
readonly userId: string;
|
|
10
|
+
readonly ipAddress: string;
|
|
11
|
+
readonly deviceInfo?: IDeviceInfo;
|
|
12
|
+
readonly location?: string;
|
|
13
|
+
readonly clientName?: string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a verifiable authentication subject.
|
|
3
|
+
* Used by the {@link VerificationService} to verify email / PIN.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface IVerifiableSubject {
|
|
8
|
+
/**
|
|
9
|
+
* Unique identifier.
|
|
10
|
+
*/
|
|
11
|
+
readonly id: string;
|
|
12
|
+
/**
|
|
13
|
+
* Email address.
|
|
14
|
+
*/
|
|
15
|
+
readonly email: string | null;
|
|
16
|
+
/**
|
|
17
|
+
* User / login name.
|
|
18
|
+
*/
|
|
19
|
+
readonly userName: string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the account has already been verified.
|
|
22
|
+
*/
|
|
23
|
+
readonly isVerified: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Current verification token stored on the entity.
|
|
26
|
+
*/
|
|
27
|
+
readonly verificationToken: string | null;
|
|
28
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { IMfaSubject } from './IMfaSubject';
|
|
2
|
+
import type { IMfaSubjectUpdate } from './IMfaSubjectUpdate';
|
|
3
|
+
/**
|
|
4
|
+
* Abstract port for reading and writing MFA state on the underlying subject entity.
|
|
5
|
+
* Used by the MfaService and all MFA channel implementations.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class MfaSubjectPort {
|
|
10
|
+
/**
|
|
11
|
+
* Find an MFA subject by its unique identifier.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
* @param id - The subject identifier.
|
|
15
|
+
* @returns The MFA subject or `null`.
|
|
16
|
+
*/
|
|
17
|
+
abstract findById(id: string): Promise<IMfaSubject | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Update MFA-related fields on the subject.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
* @param id - The subject identifier.
|
|
23
|
+
* @param data - The partial update payload.
|
|
24
|
+
*/
|
|
25
|
+
abstract updateMfaState(id: string, data: IMfaSubjectUpdate): Promise<void>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// #region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.MfaSubjectPort = void 0;
|
|
5
|
+
// #endregion
|
|
6
|
+
/**
|
|
7
|
+
* Abstract port for reading and writing MFA state on the underlying subject entity.
|
|
8
|
+
* Used by the MfaService and all MFA channel implementations.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
class MfaSubjectPort {
|
|
13
|
+
}
|
|
14
|
+
exports.MfaSubjectPort = MfaSubjectPort;
|
|
15
|
+
//# sourceMappingURL=MfaSubjectPort.js.map
|