@siran/auth-core 0.1.1 → 0.14.0
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/.vscode/settings.json +21 -0
- package/CHANGELOG.md +139 -0
- package/COMPOSITE_AUTH_SERVICE.md +104 -0
- package/package.json +1 -1
- package/src/application/policies/account-already-exists.policy.ts +23 -0
- package/src/application/policies/magic-link-token.policy.ts +23 -0
- package/src/application/policies/oauth-code.policy.ts +23 -0
- package/src/application/policies/oauth-provider.policy.ts +29 -0
- package/src/application/policies/otp-code-format.policy.ts +23 -0
- package/src/application/policies/otp-code.policy.ts +23 -0
- package/src/application/policies/otp-identifier.policy.ts +23 -0
- package/src/application/policies/password-identifier.policy.ts +23 -0
- package/src/application/policies/password-min-length.policy.ts +29 -0
- package/src/application/policies/password-present.policy.ts +23 -0
- package/src/application/policies/password-strength.policy.ts +27 -0
- package/src/application/ports/auth-preference-service.port.ts +14 -0
- package/src/application/ports/auth-service.port.ts +58 -11
- package/src/application/ports/pre-register-policy.port.ts +7 -0
- package/src/application/ports/user-existence.port.ts +3 -0
- package/src/application/services/composite-auth.service.ts +96 -0
- package/src/application/use-cases/authenticate-user.ts +17 -4
- package/src/application/use-cases/register-user.ts +28 -0
- package/src/auth-engine.factory.ts +53 -0
- package/src/auth-engine.ts +25 -0
- package/src/domain/user-account.ts +3 -9
- package/src/index.ts +16 -2
- package/tests/application/policies/magic-link-token.policy.test.ts +74 -0
- package/tests/application/policies/oauth-code.policy.test.ts +79 -0
- package/tests/application/policies/oauth-provider.policy.test.ts +76 -0
- package/tests/application/policies/otp-code-format.policy.test.ts +90 -0
- package/tests/application/policies/otp-code.policy.test.ts +55 -0
- package/tests/application/policies/otp-identifier.policy.test.ts +55 -0
- package/tests/application/policies/password-identifier.policy.test.ts +55 -0
- package/tests/application/policies/password-min-length.policy.test.ts +66 -0
- package/tests/application/policies/password-present.policy.test.ts +55 -0
- package/tests/application/policies/password-strength.policy.test.ts +66 -0
- package/tests/application/ports/auth-preferences-service.port.mock.ts +14 -0
- package/tests/application/ports/auth-service.port.mock.ts +19 -0
- package/tests/application/ports/pre-register-policy.port.mock.ts +16 -0
- package/tests/application/services/composite-auth.mock.ts +18 -0
- package/tests/application/services/composite-auth.test.ts +162 -0
- package/tests/application/use-cases/authenticate-user.test.ts +61 -14
- package/tests/application/use-cases/register-user.test.ts +89 -0
- package/tests/domain/user-account.data.ts +5 -0
- package/tsconfig.lib.json +4 -1
- package/tsconfig.spec.json +13 -1
- package/vite.config.mts +4 -1
- package/src/domain/session.ts +0 -16
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { AuthMethod, AuthResultFailure } from "@application/ports/auth-service.port.js";
|
|
2
|
+
import { registerUser } from "@application/use-cases/register-user.js";
|
|
3
|
+
import { createAuthServiceMock } from "@tests/application/ports/auth-service.port.mock.js";
|
|
4
|
+
import { createPreRegisterPolicyMock } from "@tests/application/ports/pre-register-policy.port.mock.js";
|
|
5
|
+
import { describe, expect, it } from "vitest";
|
|
6
|
+
|
|
7
|
+
describe('RegisterUser', () => {
|
|
8
|
+
it('should register a user', async () => {
|
|
9
|
+
// Given
|
|
10
|
+
const authService = createAuthServiceMock();
|
|
11
|
+
const policy = createPreRegisterPolicyMock();
|
|
12
|
+
const signUpUser = registerUser(authService, [policy]);
|
|
13
|
+
// When
|
|
14
|
+
const result = await signUpUser(
|
|
15
|
+
{ type: 'password', identifier: 'test@test.com', password: 'test' },
|
|
16
|
+
);
|
|
17
|
+
// Then
|
|
18
|
+
expect(result.ok).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should fail to register a user if a pre-register policy is violated', async () => {
|
|
22
|
+
// Given
|
|
23
|
+
const authService = createAuthServiceMock();
|
|
24
|
+
const policy = createPreRegisterPolicyMock({
|
|
25
|
+
code: 'POLICY_ERROR',
|
|
26
|
+
check: vi.fn().mockResolvedValue(false),
|
|
27
|
+
isActive: vi.fn().mockResolvedValue(true),
|
|
28
|
+
});
|
|
29
|
+
const method: AuthMethod = { type: 'password', identifier: 'test@test.com', password: 'test' };
|
|
30
|
+
const signUpUser = registerUser(authService, [policy]);
|
|
31
|
+
// When
|
|
32
|
+
const result = await signUpUser(method);
|
|
33
|
+
// Then
|
|
34
|
+
expect(policy.check).toHaveBeenCalledWith(method);
|
|
35
|
+
expect(authService.register).not.toHaveBeenCalled();
|
|
36
|
+
expect(result).toEqual({
|
|
37
|
+
ok: false,
|
|
38
|
+
error: 'PRE_REGISTER_POLICY_VIOLATED',
|
|
39
|
+
violatedPolicies: ['POLICY_ERROR']
|
|
40
|
+
} as AuthResultFailure);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should fail to register a user if active pre-register policies are violated', async () => {
|
|
44
|
+
// Given
|
|
45
|
+
const authService = createAuthServiceMock();
|
|
46
|
+
const policy1 = createPreRegisterPolicyMock({
|
|
47
|
+
code: 'POLICY_1_ERROR',
|
|
48
|
+
check: vi.fn().mockResolvedValue(false),
|
|
49
|
+
isActive: vi.fn().mockResolvedValue(false),
|
|
50
|
+
});
|
|
51
|
+
const policy2 = createPreRegisterPolicyMock({
|
|
52
|
+
code: 'POLICY_2_ERROR',
|
|
53
|
+
check: vi.fn().mockResolvedValue(false),
|
|
54
|
+
isActive: vi.fn().mockResolvedValue(true),
|
|
55
|
+
});
|
|
56
|
+
const method: AuthMethod = { type: 'password', identifier: 'test@test.com', password: 'test' };
|
|
57
|
+
const signUpUser = registerUser(authService, [policy1, policy2]);
|
|
58
|
+
// When
|
|
59
|
+
const result = await signUpUser(method);
|
|
60
|
+
// Then
|
|
61
|
+
expect(policy1.isActive).toHaveBeenCalledWith(method);
|
|
62
|
+
expect(policy2.isActive).toHaveBeenCalledWith(method);
|
|
63
|
+
expect(policy1.check).not.toHaveBeenCalled();
|
|
64
|
+
expect(policy2.check).toHaveBeenCalledWith(method);
|
|
65
|
+
expect(authService.register).not.toHaveBeenCalled();
|
|
66
|
+
expect(result).toEqual({
|
|
67
|
+
ok: false,
|
|
68
|
+
error: 'PRE_REGISTER_POLICY_VIOLATED',
|
|
69
|
+
violatedPolicies: ['POLICY_2_ERROR']
|
|
70
|
+
} as AuthResultFailure);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should register a user if the pre-register policy is deactivated', async () => {
|
|
74
|
+
// Given
|
|
75
|
+
const authService = createAuthServiceMock();
|
|
76
|
+
const policy = createPreRegisterPolicyMock({
|
|
77
|
+
isActive: vi.fn().mockResolvedValue(false),
|
|
78
|
+
});
|
|
79
|
+
const method: AuthMethod = { type: 'password', identifier: 'test@test.com', password: 'test' };
|
|
80
|
+
const signUpUser = registerUser(authService, [policy]);
|
|
81
|
+
// When
|
|
82
|
+
const result = await signUpUser(method);
|
|
83
|
+
// Then
|
|
84
|
+
expect(policy.isActive).toHaveBeenCalledWith(method);
|
|
85
|
+
expect(policy.check).not.toHaveBeenCalled();
|
|
86
|
+
expect(authService.register).toHaveBeenCalledWith(method);
|
|
87
|
+
expect(result).toEqual({ ok: true, user: { id: '1', displayName: 'test@test.com', status: 'active', isVerified: true } });
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { UserAccount } from "@domain/user-account.js";
|
|
2
|
+
|
|
3
|
+
export const activeUser: UserAccount = { id: '1', displayName: 'test@test.com', status: 'active', isVerified: true };
|
|
4
|
+
export const inactiveUser: UserAccount = { id: '1', displayName: 'test@test.com', status: 'disabled', isVerified: true };
|
|
5
|
+
export const notVerifiedUser: UserAccount = { id: '1', displayName: 'test@test.com', status: 'active', isVerified: false };
|
package/tsconfig.lib.json
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
"paths": {
|
|
8
8
|
"@domain/*": ["src/domain/*"],
|
|
9
9
|
"@application/*": ["src/application/*"],
|
|
10
|
+
"@infrastructure/*": ["src/infrastructure/*"],
|
|
11
|
+
"@root/*": ["src/*"]
|
|
10
12
|
},
|
|
11
13
|
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
|
|
12
14
|
"emitDeclarationOnly": true,
|
|
@@ -27,6 +29,7 @@
|
|
|
27
29
|
"src/**/*.test.js",
|
|
28
30
|
"src/**/*.spec.js",
|
|
29
31
|
"src/**/*.test.jsx",
|
|
30
|
-
"src/**/*.spec.jsx"
|
|
32
|
+
"src/**/*.spec.jsx",
|
|
33
|
+
"src/**/*.example.ts"
|
|
31
34
|
]
|
|
32
35
|
}
|
package/tsconfig.spec.json
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
"baseUrl": ".",
|
|
5
5
|
"paths": {
|
|
6
6
|
"@domain/*": ["src/domain/*"],
|
|
7
|
-
"@application/*": ["src/application/*"]
|
|
7
|
+
"@application/*": ["src/application/*"],
|
|
8
|
+
"@infrastructure/*": ["src/infrastructure/*"],
|
|
9
|
+
"@tests/*": ["tests/*"]
|
|
8
10
|
},
|
|
9
11
|
"outDir": "./out-tsc/vitest",
|
|
10
12
|
"types": [
|
|
@@ -30,6 +32,16 @@
|
|
|
30
32
|
"tests/**/*.test.jsx",
|
|
31
33
|
"tests/**/*.spec.jsx",
|
|
32
34
|
"tests/**/*.d.ts",
|
|
35
|
+
"tests/**/*.mock.ts",
|
|
36
|
+
"tests/**/*.mock.tsx",
|
|
37
|
+
"tests/**/*.mock.js",
|
|
38
|
+
"tests/**/*.mock.jsx",
|
|
39
|
+
"tests/**/*.mock.d.ts",
|
|
40
|
+
"tests/**/*.mock.json",
|
|
41
|
+
"tests/**/*.mock.yaml",
|
|
42
|
+
"tests/**/*.mock.yml",
|
|
43
|
+
"tests/**/*.mock.xml",
|
|
44
|
+
"tests/**/*.data.ts",
|
|
33
45
|
],
|
|
34
46
|
"references": [
|
|
35
47
|
{
|
package/vite.config.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types='vitest' />
|
|
2
|
+
import * as path from 'path';
|
|
2
3
|
import { defineConfig } from 'vite';
|
|
3
4
|
import dts from 'vite-plugin-dts';
|
|
4
|
-
import * as path from 'path';
|
|
5
5
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
6
6
|
|
|
7
7
|
export default defineConfig(() => ({
|
|
@@ -18,6 +18,9 @@ export default defineConfig(() => ({
|
|
|
18
18
|
alias: {
|
|
19
19
|
'@domain': path.resolve(__dirname, 'src/domain'),
|
|
20
20
|
'@application': path.resolve(__dirname, 'src/application'),
|
|
21
|
+
'@infrastructure': path.resolve(__dirname, 'src/infrastructure'),
|
|
22
|
+
'@root': path.resolve(__dirname, 'src'),
|
|
23
|
+
'@tests': path.resolve(__dirname, 'tests'),
|
|
21
24
|
},
|
|
22
25
|
},
|
|
23
26
|
// Uncomment this if you are using workers.
|
package/src/domain/session.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Domaine: session utilisateur Sekoliko.
|
|
3
|
-
* Ne contient pas de détails d’implémentation (cookies, tokens, etc.).
|
|
4
|
-
*/
|
|
5
|
-
export interface Session {
|
|
6
|
-
id: string;
|
|
7
|
-
userId: string;
|
|
8
|
-
createdAt: Date;
|
|
9
|
-
lastActivityAt: Date;
|
|
10
|
-
expiresAt: Date;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const isSessionActive = (session: Session, now: Date = new Date()): boolean =>
|
|
14
|
-
now < session.expiresAt;
|
|
15
|
-
|
|
16
|
-
|