@rineex/auth-core 0.0.1 → 0.0.2
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/Architecture.md +257 -0
- package/CHANGELOG.md +16 -0
- package/Definition.md +1490 -0
- package/Develop.md +0 -0
- package/RULES.md +1470 -0
- package/eslint.config.mjs +58 -0
- package/package.json +22 -21
- package/src/domain/aggregates/authentication-attempt.aggregate.ts +119 -0
- package/src/domain/entities/identity.entity.ts +13 -0
- package/src/domain/events/authentication-failed.event.ts +24 -0
- package/src/domain/events/authentication-started.event.ts +29 -0
- package/src/domain/events/authentication-succeeded.event.ts +24 -0
- package/src/domain/value-objects/auth-attempt-id.vo.ts +19 -0
- package/src/domain/value-objects/auth-method.vo.ts +21 -0
- package/src/domain/value-objects/auth-status.vo.ts +38 -0
- package/src/domain/value-objects/identity-id.vo.ts +22 -0
- package/src/index.ts +1 -0
- package/src/ports/inbound/auth-method.port.ts +18 -0
- package/src/ports/outbound/authentication-attempt.repository.port.ts +11 -0
- package/src/types/auth-context.type.ts +11 -0
- package/tsconfig.build.json +6 -0
- package/tsconfig.json +25 -0
- package/tsup.config.ts +13 -0
- package/vitest.config.ts +12 -0
- package/dist/index.d.mts +0 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -1
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import config from '@rineex/eslint-config/base';
|
|
2
|
+
import db from '@rineex/eslint-config/db';
|
|
3
|
+
|
|
4
|
+
export default [
|
|
5
|
+
...config,
|
|
6
|
+
...db,
|
|
7
|
+
|
|
8
|
+
{
|
|
9
|
+
rules: {
|
|
10
|
+
'@typescript-eslint/consistent-type-definitions': ['off'],
|
|
11
|
+
'@typescript-eslint/consistent-type-imports': 'off',
|
|
12
|
+
'@typescript-eslint/no-extraneous-class': 'off',
|
|
13
|
+
'max-params': ['error', 5],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
rules: {
|
|
18
|
+
'perfectionist/sort-imports': [
|
|
19
|
+
'error',
|
|
20
|
+
{
|
|
21
|
+
groups: [
|
|
22
|
+
'builtin', // Node.js built-in modules (e.g., 'fs', 'path')
|
|
23
|
+
'external', // External dependencies (e.g., 'react', 'lodash')
|
|
24
|
+
'nestjs',
|
|
25
|
+
'common', // Your custom group for '@/common/*'
|
|
26
|
+
'internal', // Other internal imports (e.g., '~/components/Button')
|
|
27
|
+
'parent', // Parent directory imports (e.g., '../utils')
|
|
28
|
+
'sibling', // Same directory imports (e.g., './config')
|
|
29
|
+
'index', // Index file imports (e.g., './')
|
|
30
|
+
],
|
|
31
|
+
customGroups: {
|
|
32
|
+
value: {
|
|
33
|
+
nestjs: '@nestjs/*',
|
|
34
|
+
common: '@/*', // Matches imports like '@/common/utils', '@/common/helpers', etc.
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
newlinesBetween: 'always',
|
|
39
|
+
type: 'line-length',
|
|
40
|
+
|
|
41
|
+
order: 'desc',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
'perfectionist/sort-objects': [
|
|
45
|
+
'error',
|
|
46
|
+
{
|
|
47
|
+
type: 'line-length',
|
|
48
|
+
order: 'desc',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
|
|
52
|
+
'perfectionist/sort-decorators': [
|
|
53
|
+
'error',
|
|
54
|
+
{ type: 'line-length', order: 'desc' },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
];
|
package/package.json
CHANGED
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rineex/auth-core",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Authentication Core package for Rineex core modules",
|
|
5
5
|
"author": "Rineex Team",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
|
-
"files": [
|
|
10
|
-
"dist/**"
|
|
11
|
-
],
|
|
12
|
-
"sideEffects": false,
|
|
13
|
-
"devDependencies": {
|
|
14
|
-
"@changesets/cli": "2.29.8",
|
|
15
|
-
"@types/node": "24.10.4",
|
|
16
|
-
"@vitest/ui": "4.0.16",
|
|
17
|
-
"tslib": "2.8.1",
|
|
18
|
-
"tsup": "8.5.1",
|
|
19
|
-
"typescript": "5.9.3",
|
|
20
|
-
"vite-tsconfig-paths": "6.0.2",
|
|
21
|
-
"vitest": "4.0.16",
|
|
22
|
-
"@rineex/eslint-config": "0.0.0",
|
|
23
|
-
"@rineex/typescript-config": "0.0.0"
|
|
24
|
-
},
|
|
25
9
|
"keywords": [
|
|
26
10
|
"rineex",
|
|
27
|
-
"auth",
|
|
28
11
|
"authentication",
|
|
12
|
+
"auth",
|
|
29
13
|
"social-login",
|
|
30
14
|
"otp",
|
|
31
15
|
"passwordless",
|
|
32
16
|
"sso"
|
|
33
17
|
],
|
|
34
|
-
"license": "Apache-2.0",
|
|
35
18
|
"publishConfig": {
|
|
36
19
|
"provenance": true,
|
|
37
20
|
"access": "public",
|
|
38
21
|
"registry": "https://registry.npmjs.org"
|
|
39
22
|
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@changesets/cli": "2.29.8",
|
|
25
|
+
"@types/node": "24.10.4",
|
|
26
|
+
"@vitest/ui": "4.0.16",
|
|
27
|
+
"tslib": "2.8.1",
|
|
28
|
+
"tsup": "8.5.1",
|
|
29
|
+
"type-fest": "5.3.1",
|
|
30
|
+
"typescript": "5.9.3",
|
|
31
|
+
"vite-tsconfig-paths": "6.0.2",
|
|
32
|
+
"vitest": "4.0.16",
|
|
33
|
+
"@rineex/eslint-config": "0.0.0",
|
|
34
|
+
"@rineex/typescript-config": "0.0.0"
|
|
35
|
+
},
|
|
40
36
|
"repository": {
|
|
41
37
|
"type": "git",
|
|
42
38
|
"url": "https://github.com/rineex/core.git",
|
|
43
|
-
"directory": "packages/
|
|
39
|
+
"directory": "packages/authentication/core"
|
|
40
|
+
},
|
|
41
|
+
"license": "Apache-2.0",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@rineex/ddd": "1.5.1"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"test": "vitest run --passWithNoTests",
|
|
47
|
+
"test:watch": "vitest --watch --passWithNoTests",
|
|
47
48
|
"lint": "eslint 'src/**/*.ts'",
|
|
48
49
|
"check-types": "tsc --noEmit",
|
|
49
50
|
"build": "tsup"
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AggregateRoot } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
import { AuthenticationSucceededEvent } from '../events/authentication-succeeded.event';
|
|
4
|
+
import { AuthenticationStartedEvent } from '../events/authentication-started.event';
|
|
5
|
+
import { AuthenticationFailedEvent } from '../events/authentication-failed.event';
|
|
6
|
+
import { AuthAttemptId } from '../value-objects/auth-attempt-id.vo';
|
|
7
|
+
import { AuthStatus } from '../value-objects/auth-status.vo';
|
|
8
|
+
import { AuthMethod } from '../value-objects/auth-method.vo';
|
|
9
|
+
import { IdentityId } from '../value-objects/identity-id.vo';
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
status: AuthStatus;
|
|
13
|
+
method: AuthMethod;
|
|
14
|
+
identityId?: IdentityId;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Aggregate Root representing a single authentication attempt.
|
|
19
|
+
*
|
|
20
|
+
* Responsibilities:
|
|
21
|
+
* - Enforce authentication lifecycle invariants
|
|
22
|
+
* - Emit auditable domain events
|
|
23
|
+
* - Prevent invalid state transitions
|
|
24
|
+
*
|
|
25
|
+
* This aggregate DOES NOT:
|
|
26
|
+
* - Perform authentication
|
|
27
|
+
* - Talk to infrastructure
|
|
28
|
+
* - Know about HTTP or sessions
|
|
29
|
+
*/
|
|
30
|
+
export class AuthenticationAttempt extends AggregateRoot<Props> {
|
|
31
|
+
private constructor(id: AuthAttemptId, props: Props) {
|
|
32
|
+
super({
|
|
33
|
+
createdAt: new Date(),
|
|
34
|
+
props,
|
|
35
|
+
id,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// This "casts" the ID for this specific class only
|
|
40
|
+
public override get id(): AuthAttemptId {
|
|
41
|
+
return super.id as AuthAttemptId;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Factory method to start a new authentication attempt.
|
|
46
|
+
*/
|
|
47
|
+
static start(
|
|
48
|
+
id: AuthAttemptId,
|
|
49
|
+
method: AuthMethod,
|
|
50
|
+
identityId?: IdentityId,
|
|
51
|
+
): AuthenticationAttempt {
|
|
52
|
+
const attempt = new AuthenticationAttempt(id, {
|
|
53
|
+
status: AuthStatus.create('PENDING'),
|
|
54
|
+
identityId,
|
|
55
|
+
method,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
attempt.addEvent(new AuthenticationStartedEvent(id, method));
|
|
59
|
+
|
|
60
|
+
return attempt;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Marks the authentication attempt as successful.
|
|
65
|
+
*
|
|
66
|
+
* @throws Error if already completed
|
|
67
|
+
*/
|
|
68
|
+
succeed(): void {
|
|
69
|
+
if (this.props.status.isNot('PENDING')) {
|
|
70
|
+
throw new Error('Authentication attempt already completed');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.updateProps(props => ({
|
|
74
|
+
...props,
|
|
75
|
+
status: AuthStatus.create('SUCCEEDED'),
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
const ev = new AuthenticationSucceededEvent(this.id);
|
|
79
|
+
|
|
80
|
+
this.addEvent(ev);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Marks the authentication attempt as failed.
|
|
85
|
+
*
|
|
86
|
+
* @throws Error if already completed
|
|
87
|
+
*/
|
|
88
|
+
fail(reason: string): void {
|
|
89
|
+
if (this.props.status.isNot('PENDING')) {
|
|
90
|
+
throw new Error('Authentication attempt already completed');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!reason || reason.length < 3) {
|
|
94
|
+
throw new Error('Failure reason must be provided');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this.updateProps(props => ({
|
|
98
|
+
...props,
|
|
99
|
+
status: AuthStatus.create('FAILED'),
|
|
100
|
+
}));
|
|
101
|
+
|
|
102
|
+
this.addEvent(new AuthenticationFailedEvent(this.id));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Aggregate invariant validation.
|
|
107
|
+
*
|
|
108
|
+
* Called automatically before domain events are added.
|
|
109
|
+
*/
|
|
110
|
+
validate(): void {
|
|
111
|
+
if (!this.props.method) {
|
|
112
|
+
throw new Error('AuthenticationAttempt must have a method');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!this.props.status) {
|
|
116
|
+
throw new Error('AuthenticationAttempt must have a status');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Entity } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
import { IdentityId } from '../value-objects/identity-id.vo';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents an authenticated or authenticating identity.
|
|
7
|
+
*
|
|
8
|
+
* This entity is intentionally minimal.
|
|
9
|
+
* All profile, permissions, and roles belong elsewhere.
|
|
10
|
+
*/
|
|
11
|
+
export class Identity extends Entity<IdentityId> {
|
|
12
|
+
validate(): void {}
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DomainEvent } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
import { AuthAttemptId } from '../value-objects/auth-attempt-id.vo';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Emitted when an authentication attempt failed.
|
|
7
|
+
*/
|
|
8
|
+
export class AuthenticationFailedEvent extends DomainEvent {
|
|
9
|
+
public get eventName(): string {
|
|
10
|
+
return 'authentication.auth_attempt.failed';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
constructor(public readonly attemptId: AuthAttemptId) {
|
|
14
|
+
super({
|
|
15
|
+
payload: {
|
|
16
|
+
attemptId: attemptId.toString(),
|
|
17
|
+
},
|
|
18
|
+
aggregateId: attemptId.toString(),
|
|
19
|
+
id: crypto.randomUUID(),
|
|
20
|
+
occurredAt: Date.now(),
|
|
21
|
+
schemaVersion: 1,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DomainEvent } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
import { AuthAttemptId } from '../value-objects/auth-attempt-id.vo';
|
|
4
|
+
import { AuthMethod } from '../value-objects/auth-method.vo';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Emitted when an authentication attempt begins.
|
|
8
|
+
*/
|
|
9
|
+
export class AuthenticationStartedEvent extends DomainEvent {
|
|
10
|
+
public get eventName(): string {
|
|
11
|
+
return 'authentication.authentication_started';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
public readonly attemptId: AuthAttemptId,
|
|
16
|
+
public readonly method: AuthMethod,
|
|
17
|
+
) {
|
|
18
|
+
super({
|
|
19
|
+
payload: {
|
|
20
|
+
attemptId: attemptId.toString(),
|
|
21
|
+
method: method.toString(),
|
|
22
|
+
},
|
|
23
|
+
aggregateId: attemptId.toString(),
|
|
24
|
+
id: crypto.randomUUID(),
|
|
25
|
+
occurredAt: Date.now(),
|
|
26
|
+
schemaVersion: 1,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DomainEvent } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
import { AuthAttemptId } from '../value-objects/auth-attempt-id.vo';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Emitted when an authentication attempt succeeds.
|
|
7
|
+
*/
|
|
8
|
+
export class AuthenticationSucceededEvent extends DomainEvent {
|
|
9
|
+
public get eventName(): string {
|
|
10
|
+
return 'authentication.auth_attempt.succeeded';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
constructor(public readonly attemptId: AuthAttemptId) {
|
|
14
|
+
super({
|
|
15
|
+
payload: {
|
|
16
|
+
attemptId: attemptId.toString(),
|
|
17
|
+
},
|
|
18
|
+
aggregateId: attemptId.toString(),
|
|
19
|
+
id: crypto.randomUUID(),
|
|
20
|
+
occurredAt: Date.now(),
|
|
21
|
+
schemaVersion: 1,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { UUID } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a globally unique identifier for an authentication attempt.
|
|
5
|
+
*
|
|
6
|
+
* This ID is used for:
|
|
7
|
+
* - Correlation across logs
|
|
8
|
+
* - Event causation
|
|
9
|
+
* - Security auditing
|
|
10
|
+
*
|
|
11
|
+
* Must be generated externally (UUIDv7 recommended).
|
|
12
|
+
*/
|
|
13
|
+
export class AuthAttemptId extends UUID {
|
|
14
|
+
protected validate(value: string): void {
|
|
15
|
+
if (!value || value.length < 16) {
|
|
16
|
+
throw new Error('AuthAttemptId must be a valid non-empty identifier');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PrimitiveValueObject } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents the authentication method requested or used.
|
|
5
|
+
*
|
|
6
|
+
* Examples:
|
|
7
|
+
* - passwordless
|
|
8
|
+
* - otp
|
|
9
|
+
* - oauth
|
|
10
|
+
* - oidc
|
|
11
|
+
* - passkey
|
|
12
|
+
*
|
|
13
|
+
* This is a value object, NOT a strategy.
|
|
14
|
+
*/
|
|
15
|
+
export class AuthMethod extends PrimitiveValueObject<string> {
|
|
16
|
+
protected validate(value: string): void {
|
|
17
|
+
if (!value) {
|
|
18
|
+
throw new Error('AuthMethod cannot be empty');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { PrimitiveValueObject } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
type AuthStatusType = 'FAILED' | 'PENDING' | 'SUCCEEDED';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents the lifecycle state of an authentication attempt.
|
|
7
|
+
*
|
|
8
|
+
* This is intentionally restrictive to avoid invalid transitions.
|
|
9
|
+
*/
|
|
10
|
+
export class AuthStatus extends PrimitiveValueObject<AuthStatusType> {
|
|
11
|
+
protected validate(value: AuthStatusType): void {
|
|
12
|
+
if (!['FAILED', 'PENDING', 'SUCCEEDED'].includes(value)) {
|
|
13
|
+
throw new Error(`Invalid AuthStatus: ${value}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Checks if the current auth status matches the provided value.
|
|
19
|
+
* @param value - The auth status type to compare against
|
|
20
|
+
* @returns True if the current status matches the provided value, false otherwise
|
|
21
|
+
*/
|
|
22
|
+
public is(value: AuthStatusType): boolean {
|
|
23
|
+
return this.value === value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Checks if the current authentication status is not equal to the provided value.
|
|
28
|
+
* @param value - The authentication status type to compare against
|
|
29
|
+
* @returns True if the current status differs from the provided value, false otherwise
|
|
30
|
+
*/
|
|
31
|
+
public isNot(value: AuthStatusType): boolean {
|
|
32
|
+
return this.value !== value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static create(value: AuthStatusType): AuthStatus {
|
|
36
|
+
return new AuthStatus(value);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PrimitiveValueObject } from '@rineex/ddd';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents the canonical identity identifier in the auth domain.
|
|
5
|
+
*
|
|
6
|
+
* This does NOT imply:
|
|
7
|
+
* - user
|
|
8
|
+
* - account
|
|
9
|
+
* - profile
|
|
10
|
+
*
|
|
11
|
+
* It is intentionally abstract to support:
|
|
12
|
+
* - enterprise SSO
|
|
13
|
+
* - external IdPs
|
|
14
|
+
* - service identities
|
|
15
|
+
*/
|
|
16
|
+
export class IdentityId extends PrimitiveValueObject<string> {
|
|
17
|
+
protected validate(value: string): void {
|
|
18
|
+
if (!value || value.length < 8) {
|
|
19
|
+
throw new Error('IdentityId must be a valid identifier');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AuthMethod } from '@/domain/value-objects/auth-method.vo';
|
|
2
|
+
import { AuthContext } from '@/types/auth-context.type';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Contract implemented by authentication method modules.
|
|
6
|
+
*
|
|
7
|
+
* Examples:
|
|
8
|
+
* - OTP
|
|
9
|
+
* - OAuth
|
|
10
|
+
* - Passkeys
|
|
11
|
+
*
|
|
12
|
+
* Auth-core depends on this abstraction, not implementations.
|
|
13
|
+
*/
|
|
14
|
+
export type AuthMethodPort = {
|
|
15
|
+
readonly method: AuthMethod;
|
|
16
|
+
|
|
17
|
+
authenticate: (context: AuthContext) => Promise<void>;
|
|
18
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AuthenticationAttempt } from '@/domain/aggregates/authentication-attempt.aggregate';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Persistence port for authentication attempts.
|
|
5
|
+
*
|
|
6
|
+
* Implementation is infrastructure-specific.
|
|
7
|
+
*/
|
|
8
|
+
export type AuthenticationAttemptRepositoryPort = {
|
|
9
|
+
save: (attempt: AuthenticationAttemptRepositoryPort) => Promise<void>;
|
|
10
|
+
findById: (id: string) => Promise<AuthenticationAttempt | null>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context passed across authentication boundaries.
|
|
3
|
+
*
|
|
4
|
+
* This type is intentionally open-ended and extensible.
|
|
5
|
+
*/
|
|
6
|
+
export type AuthContext = {
|
|
7
|
+
readonly correlationId: string;
|
|
8
|
+
readonly ipAddress?: string;
|
|
9
|
+
readonly userAgent?: string;
|
|
10
|
+
readonly metadata?: Record<string, unknown>;
|
|
11
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"noImplicitAny": false,
|
|
6
|
+
"noUnusedLocals": false,
|
|
7
|
+
"importHelpers": true,
|
|
8
|
+
"removeComments": false,
|
|
9
|
+
"noLib": false,
|
|
10
|
+
"emitDecoratorMetadata": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"experimentalDecorators": true,
|
|
13
|
+
"target": "es6",
|
|
14
|
+
"sourceMap": false,
|
|
15
|
+
"outDir": "./dist",
|
|
16
|
+
"rootDir": ".",
|
|
17
|
+
"paths": {
|
|
18
|
+
"@/*": ["./src/*"]
|
|
19
|
+
},
|
|
20
|
+
"lib": ["es7", "ES2021.WeakRef", "ES2022"],
|
|
21
|
+
"types": ["node"]
|
|
22
|
+
},
|
|
23
|
+
"include": ["src/**/*", "tsup.config.ts", "vitest.config.ts"],
|
|
24
|
+
"exclude": ["node_modules"]
|
|
25
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineConfig } from 'tsup';
|
|
2
|
+
|
|
3
|
+
export default defineConfig(() => ({
|
|
4
|
+
// eslint-disable-next-line n/no-process-env
|
|
5
|
+
minify: process.env.CI === 'true',
|
|
6
|
+
tsconfig: 'tsconfig.build.json',
|
|
7
|
+
entry: ['src/index.ts'],
|
|
8
|
+
format: ['cjs', 'esm'],
|
|
9
|
+
splitting: false,
|
|
10
|
+
sourcemap: true,
|
|
11
|
+
clean: true,
|
|
12
|
+
dts: true,
|
|
13
|
+
}));
|
package/vitest.config.ts
ADDED
package/dist/index.d.mts
DELETED
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var t=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var d=(o,e,x,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of b(e))!c.call(o,p)&&p!==x&&t(o,p,{get:()=>e[p],enumerable:!(r=a(e,p))||r.enumerable});return o};var f=o=>d(t({},"__esModule",{value:!0}),o);var g={};module.exports=f(g);
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Auth Core Package for Rineex\n * Provides core authentication and authorization functionality\n */\n\nexport {};\n"],"mappings":"kWAAA,IAAAA,EAAA,kBAAAC,EAAAD","names":["index_exports","__toCommonJS"]}
|
package/dist/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|