@rineex/auth-core 0.1.0 → 0.1.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/package.json +6 -3
- package/Architecture.md +0 -257
- package/CHANGELOG.md +0 -62
- package/Definition.md +0 -1490
- package/Develop.md +0 -0
- package/RULES.md +0 -1470
- package/eslint.config.mjs +0 -59
- package/src/application/mfa/events/challenge-issue-observability.event.ts +0 -18
- package/src/application/mfa/events/session-started-observability.event.ts +0 -18
- package/src/application/mfa/events/verification-failed-observability.event.ts +0 -14
- package/src/application/mfa/events/verification-succeeded-observibility.event.ts +0 -12
- package/src/application/mfa/issue-mfa-challenge.application-service.ts +0 -75
- package/src/application/mfa/start-mfa-session.application-service.ts +0 -90
- package/src/application/mfa/verify-mfa.application-service.ts +0 -61
- package/src/application/services/auth-orchestrator.service.ts +0 -77
- package/src/application/services/oauth-authorize.service.ts +0 -12
- package/src/domain/identity/aggregates/authentication-attempt.aggregate.ts +0 -136
- package/src/domain/identity/aggregates/index.ts +0 -1
- package/src/domain/identity/entities/identity.entity.ts +0 -126
- package/src/domain/identity/entities/index.ts +0 -1
- package/src/domain/identity/events/authentication-failed.event.ts +0 -24
- package/src/domain/identity/events/authentication-started.event.ts +0 -29
- package/src/domain/identity/events/authentication-succeeded.event.ts +0 -24
- package/src/domain/identity/events/index.ts +0 -3
- package/src/domain/identity/index.ts +0 -4
- package/src/domain/identity/value-objects/__tests__/auth-attempt-id.vo.spec.ts +0 -42
- package/src/domain/identity/value-objects/__tests__/auth-factor.vo.spec.ts +0 -39
- package/src/domain/identity/value-objects/__tests__/auth-method.vo.spec.ts +0 -0
- package/src/domain/identity/value-objects/auth-attempt-id.vo.ts +0 -23
- package/src/domain/identity/value-objects/auth-factor.vo.ts +0 -17
- package/src/domain/identity/value-objects/auth-method.vo.ts +0 -34
- package/src/domain/identity/value-objects/auth-policy.vo.ts +0 -19
- package/src/domain/identity/value-objects/auth-status.vo.ts +0 -38
- package/src/domain/identity/value-objects/identity-id.vo.ts +0 -26
- package/src/domain/identity/value-objects/identity-provider.vo.ts +0 -13
- package/src/domain/identity/value-objects/index.ts +0 -8
- package/src/domain/identity/value-objects/risk-signal.vo.ts +0 -17
- package/src/domain/index.ts +0 -5
- package/src/domain/mfa/aggregates/mfa-session.aggregate.ts +0 -84
- package/src/domain/mfa/entities/mfa-challenge.entity.ts +0 -70
- package/src/domain/mfa/types/mfa-challenge-registry.ts +0 -21
- package/src/domain/mfa/value-objects/mfa-challenge-id.vo.ts +0 -19
- package/src/domain/mfa/value-objects/mfa-challenge-status.vo.ts +0 -31
- package/src/domain/mfa/value-objects/mfa-session-id.vo.ts +0 -19
- package/src/domain/mfa/violations/mfa-active-challenge-exists.violation.ts +0 -10
- package/src/domain/mfa/violations/mfa-already-verified.violation.ts +0 -10
- package/src/domain/mfa/violations/mfa-attempts-exceeded.violation.ts +0 -17
- package/src/domain/mfa/violations/mfa-expired.violation.ts +0 -10
- package/src/domain/oauth/aggregates/oauth-authorization.aggregate.ts +0 -106
- package/src/domain/oauth/aggregates/oauth-authorize.service.ts +0 -0
- package/src/domain/oauth/entities/oauth-authorization.entity.ts +0 -50
- package/src/domain/oauth/value-objects/authorization-code-id.vo.ts +0 -9
- package/src/domain/oauth/value-objects/authorization-code.vo.ts +0 -18
- package/src/domain/oauth/value-objects/client-id.vo.ts +0 -9
- package/src/domain/oauth/value-objects/code-challenge-method.vo.ts +0 -15
- package/src/domain/oauth/value-objects/code-challenge.vo.ts +0 -24
- package/src/domain/oauth/value-objects/oauth-authorization-id.vo.ts +0 -19
- package/src/domain/oauth/value-objects/oauth-provider.vo.ts +0 -15
- package/src/domain/oauth/value-objects/pkce.vo.ts +0 -29
- package/src/domain/oauth/value-objects/redirect-uri.vo.ts +0 -19
- package/src/domain/oauth/value-objects/scope-set.vo.ts +0 -37
- package/src/domain/oauth/violations/authorization-already-used.violation.ts +0 -10
- package/src/domain/oauth/violations/authorization-expired.violation.ts +0 -10
- package/src/domain/oauth/violations/consent-required.violation.ts +0 -10
- package/src/domain/oauth/violations/invalid-authorization-code.violation.ts +0 -12
- package/src/domain/oauth/violations/invalid-oauth-provider.violation.ts +0 -13
- package/src/domain/oauth/violations/invalid-pkce.violation.ts +0 -12
- package/src/domain/oauth/violations/invalid-redirect-uri.violation.ts +0 -10
- package/src/domain/policy/contracts/auth-policy-context.ts +0 -27
- package/src/domain/policy/contracts/auth-policy-decision.ts +0 -7
- package/src/domain/policy/contracts/auth-policy.ts +0 -17
- package/src/domain/policy/contracts/index.ts +0 -3
- package/src/domain/policy/engine/auth-policy-engine.ts +0 -41
- package/src/domain/policy/index.ts +0 -2
- package/src/domain/session/entities/session.entity.ts +0 -82
- package/src/domain/session/value-objects/session-id.vo.ts +0 -10
- package/src/domain/token/aggregates/token.aggregate.ts +0 -34
- package/src/domain/token/value-objects/auth-token.vo.ts +0 -29
- package/src/domain/token/value-objects/session-token.vo.ts +0 -14
- package/src/domain/violations/auth-domain.violation.ts +0 -9
- package/src/domain/violations/invalid-auth-token.violation.ts +0 -13
- package/src/domain/violations/invalid-scope.violation.ts +0 -10
- package/src/domain/violations/invalid-session.violation.ts +0 -13
- package/src/index.ts +0 -3
- package/src/ports/inbound/auth-method.port.ts +0 -18
- package/src/ports/inbound/index.ts +0 -2
- package/src/ports/inbound/start-auth.command.ts +0 -28
- package/src/ports/index.ts +0 -2
- package/src/ports/log/log.port.ts +0 -25
- package/src/ports/mfa/mfa-clock.port.ts +0 -11
- package/src/ports/mfa/mfa-session-id-generator.port.ts +0 -15
- package/src/ports/mfa/mfa-session-repository.port.ts +0 -31
- package/src/ports/observability/observability-event.port.ts +0 -16
- package/src/ports/outbound/authentication-attempt.repository.port.ts +0 -11
- package/src/ports/outbound/domain-event-publisher.port.ts +0 -13
- package/src/ports/outbound/index.ts +0 -2
- package/src/ports/outbound/session.repository.port.ts +0 -9
- package/src/ports/repositories/oauth-authorization.repository.ts +0 -21
- package/src/ports/repositories/token.repository.ts +0 -11
- package/src/types/auth-context.type.ts +0 -11
- package/src/types/auth-factor.type.ts +0 -10
- package/src/types/auth-method.type.ts +0 -20
- package/src/types/auth-policy.type.ts +0 -16
- package/src/types/identity-provider.type.ts +0 -8
- package/src/types/index.ts +0 -6
- package/src/types/observability-event.ts +0 -33
- package/src/types/risk-signal.type.ts +0 -11
- package/src/utils/default-if-blank.util.ts +0 -46
- package/tsconfig.build.json +0 -6
- package/tsconfig.json +0 -30
- package/tsup.config.ts +0 -13
- package/vitest.config.ts +0 -12
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { AuthPolicyDecision } from '../contracts/auth-policy-decision';
|
|
2
|
-
import { AuthPolicyContext } from '../contracts/auth-policy-context';
|
|
3
|
-
import { AuthPolicyEvaluator } from '../contracts/auth-policy';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Coordinates multiple authentication policies
|
|
7
|
-
* and produces a final decision.
|
|
8
|
-
*/
|
|
9
|
-
export class AuthPolicyEngine {
|
|
10
|
-
private readonly policies: readonly AuthPolicyEvaluator[];
|
|
11
|
-
|
|
12
|
-
constructor(policies: readonly AuthPolicyEvaluator[]) {
|
|
13
|
-
this.policies = policies;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Evaluates all policies in order.
|
|
18
|
-
* First hard-deny wins.
|
|
19
|
-
*/
|
|
20
|
-
public evaluate(context: AuthPolicyContext): AuthPolicyDecision {
|
|
21
|
-
let requiresStepUp = false;
|
|
22
|
-
|
|
23
|
-
for (const policy of this.policies) {
|
|
24
|
-
const decision = policy.evaluate(context);
|
|
25
|
-
if (!decision) continue;
|
|
26
|
-
|
|
27
|
-
if (decision.allowed === false) {
|
|
28
|
-
return decision;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (decision.requiresStepUp) {
|
|
32
|
-
requiresStepUp = true;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
requiresStepUp,
|
|
38
|
-
allowed: true,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { SessionToken } from '@/domain/token/value-objects/session-token.vo';
|
|
2
|
-
import { defaultIfNilOrEmpty } from '@/utils/default-if-blank.util';
|
|
3
|
-
import { CreateEntityProps, Entity } from '@rineex/ddd';
|
|
4
|
-
import { IdentityId } from '@/domain/identity';
|
|
5
|
-
|
|
6
|
-
import { SessionId } from '../value-objects/session-id.vo';
|
|
7
|
-
|
|
8
|
-
interface CreateSessionProps extends CreateEntityProps<SessionId> {
|
|
9
|
-
readonly identityId: IdentityId;
|
|
10
|
-
readonly token: SessionToken;
|
|
11
|
-
readonly expiresAt: Date;
|
|
12
|
-
readonly revokedAt?: Date;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class Session extends Entity<SessionId> {
|
|
16
|
-
private _identityId: IdentityId;
|
|
17
|
-
private _token: SessionToken;
|
|
18
|
-
private _expiresAt: Date;
|
|
19
|
-
private _revokedAt?: Date;
|
|
20
|
-
|
|
21
|
-
protected constructor({ createdAt, id, ...props }: CreateSessionProps) {
|
|
22
|
-
super({ createdAt, id });
|
|
23
|
-
|
|
24
|
-
this._expiresAt = props.expiresAt;
|
|
25
|
-
this._revokedAt = props.revokedAt;
|
|
26
|
-
this._identityId = props.identityId;
|
|
27
|
-
this._token = props.token;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public static create(props: CreateSessionProps): Session {
|
|
31
|
-
return new Session(props);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
toObject(): Record<string, unknown> {
|
|
35
|
-
return {
|
|
36
|
-
identityId: this._identityId.getValue(),
|
|
37
|
-
revokedAt: this._revokedAt?.toString(),
|
|
38
|
-
expiresAt: this._expiresAt.toString(),
|
|
39
|
-
revoked: !!this._revokedAt,
|
|
40
|
-
id: this.id.getValue(),
|
|
41
|
-
token: this._token,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
revoke(at: Date): void {
|
|
46
|
-
if (this._revokedAt) return;
|
|
47
|
-
|
|
48
|
-
this.mutate(draft => {
|
|
49
|
-
draft._revokedAt = at;
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public isActive(now = new Date()): boolean {
|
|
54
|
-
if (this._revokedAt) return false;
|
|
55
|
-
|
|
56
|
-
return now < this._expiresAt;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
protected snapshot() {
|
|
60
|
-
return {
|
|
61
|
-
revokedAt: defaultIfNilOrEmpty(this._revokedAt?.toISOString()),
|
|
62
|
-
expiresAt: this._expiresAt.toISOString(),
|
|
63
|
-
identityId: this._identityId.toJSON(),
|
|
64
|
-
token: this._token.toJSON(),
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
protected restore(snapshot: Record<string, unknown>): void {
|
|
69
|
-
this._revokedAt = snapshot?.revokedAt
|
|
70
|
-
? new Date(snapshot.revokedAt as string)
|
|
71
|
-
: undefined;
|
|
72
|
-
this._expiresAt = new Date(snapshot.expiresAt as string);
|
|
73
|
-
this._identityId = IdentityId.create(snapshot.identityId as string);
|
|
74
|
-
this._token = SessionToken.create(snapshot.token as string);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
validate(): void {
|
|
78
|
-
if (this._expiresAt <= new Date(0)) {
|
|
79
|
-
throw new Error('Session expiration must be valid');
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { InvalidSessionViolation } from '@/domain/violations/invalid-session.violation';
|
|
2
|
-
import { PrimitiveValueObject } from '@rineex/ddd';
|
|
3
|
-
|
|
4
|
-
export class SessionId extends PrimitiveValueObject<string> {
|
|
5
|
-
protected validate(value: string): void {
|
|
6
|
-
if (!value || value.length < 16) {
|
|
7
|
-
throw InvalidSessionViolation.create();
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { AggregateRoot, CreateEntityProps } from '@rineex/ddd';
|
|
2
|
-
import { IdentityId } from '@/domain/identity';
|
|
3
|
-
|
|
4
|
-
interface TokenProps extends CreateEntityProps<IdentityId> {
|
|
5
|
-
readonly identityId: IdentityId;
|
|
6
|
-
readonly expiresAt: Date;
|
|
7
|
-
revokedAt?: Date;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class Token extends AggregateRoot<IdentityId> {
|
|
11
|
-
protected constructor(private props: TokenProps) {
|
|
12
|
-
super(props);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public revoke(at: Date): void {
|
|
16
|
-
if (this.props.revokedAt) return;
|
|
17
|
-
|
|
18
|
-
this.mutate(draft => {
|
|
19
|
-
draft.revokedAt = at;
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
public isActive(now = new Date()): boolean {
|
|
24
|
-
return (
|
|
25
|
-
!this.props.revokedAt && this.props.expiresAt.getTime() > now.getTime()
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
validate(): void {
|
|
30
|
-
if (this.props.expiresAt.getTime() <= Date.now()) {
|
|
31
|
-
throw new Error('Token already expired');
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { InvalidAuthTokenViolation } from '@/domain/violations/invalid-auth-token.violation';
|
|
2
|
-
import { PrimitiveValueObject } from '@rineex/ddd';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Represents a cryptographic authentication token.
|
|
6
|
-
*
|
|
7
|
-
* IMPORTANT:
|
|
8
|
-
* - This is NOT a JWT
|
|
9
|
-
* - This is NOT a bearer string
|
|
10
|
-
* - This is a domain-level proof of authentication
|
|
11
|
-
*
|
|
12
|
-
* Concrete formats live in adapters.
|
|
13
|
-
*/
|
|
14
|
-
export abstract class AuthToken extends PrimitiveValueObject<string> {
|
|
15
|
-
/**
|
|
16
|
-
* Token type identifier.
|
|
17
|
-
* Used for routing to correct adapters.
|
|
18
|
-
*/
|
|
19
|
-
abstract readonly type: string;
|
|
20
|
-
|
|
21
|
-
protected validate(value: string): void {
|
|
22
|
-
if (value.length < 32) {
|
|
23
|
-
throw InvalidAuthTokenViolation.create({
|
|
24
|
-
actualLength: value.length,
|
|
25
|
-
minLength: 32,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { AuthToken } from './auth-token.vo';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Token bound to a session lifecycle.
|
|
5
|
-
*/
|
|
6
|
-
export class SessionToken extends AuthToken {
|
|
7
|
-
get type() {
|
|
8
|
-
return 'session';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
public static create(value: string): SessionToken {
|
|
12
|
-
return new SessionToken(value);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { DomainViolation } from '@rineex/ddd';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Base class for all authentication domain violations.
|
|
5
|
-
*
|
|
6
|
-
* Auth domain MUST only throw DomainViolation objects.
|
|
7
|
-
* Mapping to native Error happens at application or adapter layer.
|
|
8
|
-
*/
|
|
9
|
-
export abstract class AuthDomainViolation extends DomainViolation {}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { AuthDomainViolation } from './auth-domain.violation';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Raised when an authentication token violates domain invariants.
|
|
5
|
-
*/
|
|
6
|
-
export class InvalidAuthTokenViolation extends AuthDomainViolation {
|
|
7
|
-
readonly code = 'AUTH_TOKEN_INVALID';
|
|
8
|
-
readonly message = 'Authentication token is invalid';
|
|
9
|
-
|
|
10
|
-
public static create(details: { actualLength: number; minLength: number }) {
|
|
11
|
-
return new InvalidAuthTokenViolation(details);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { DomainViolation } from '@rineex/ddd';
|
|
2
|
-
|
|
3
|
-
export class InvalidScopeViolation extends DomainViolation {
|
|
4
|
-
public readonly code = 'auth.scope.invalid';
|
|
5
|
-
public readonly message = 'Scope format is invalid';
|
|
6
|
-
|
|
7
|
-
public static create(): InvalidScopeViolation {
|
|
8
|
-
return new InvalidScopeViolation();
|
|
9
|
-
}
|
|
10
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { AuthDomainViolation } from './auth-domain.violation';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Raised when a session invariant is violated.
|
|
5
|
-
*/
|
|
6
|
-
export class InvalidSessionViolation extends AuthDomainViolation {
|
|
7
|
-
readonly code = 'session.invalid';
|
|
8
|
-
readonly message = 'Session state is invalid';
|
|
9
|
-
|
|
10
|
-
public static create(): InvalidSessionViolation {
|
|
11
|
-
return new InvalidSessionViolation();
|
|
12
|
-
}
|
|
13
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { AuthMethod } from '@/domain/identity/value-objects';
|
|
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
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { AuthMethodName } from '@/types/auth-method.type';
|
|
2
|
-
import { AuthContext } from '@/types/auth-context.type';
|
|
3
|
-
import { IdentityId } from '@/domain';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Command representing a request to start authentication.
|
|
7
|
-
*
|
|
8
|
-
* This is a pure use-case input.
|
|
9
|
-
* It is NOT tied to HTTP, RPC, GraphQL, or CLI.
|
|
10
|
-
*/
|
|
11
|
-
export type StartAuthenticationCommand = {
|
|
12
|
-
/**
|
|
13
|
-
* Authentication method requested.
|
|
14
|
-
* Strongly typed and autocomplete-safe.
|
|
15
|
-
*/
|
|
16
|
-
readonly method: AuthMethodName;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Optional identity hint.
|
|
20
|
-
* Used for passwordless, SSO, or known users.
|
|
21
|
-
*/
|
|
22
|
-
readonly identityId?: IdentityId;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Execution context for auditing, correlation, and risk.
|
|
26
|
-
*/
|
|
27
|
-
readonly context: AuthContext;
|
|
28
|
-
};
|
package/src/ports/index.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Application-level logger port.
|
|
3
|
-
*
|
|
4
|
-
* Must be:
|
|
5
|
-
* - side-effect only
|
|
6
|
-
* - non-throwing
|
|
7
|
-
* - fast
|
|
8
|
-
*
|
|
9
|
-
* Domain must never depend on this.
|
|
10
|
-
*/
|
|
11
|
-
export type LoggerPort = {
|
|
12
|
-
info: (message: string, metadata?: Readonly<Record<string, unknown>>) => void;
|
|
13
|
-
|
|
14
|
-
debug: (
|
|
15
|
-
message: string,
|
|
16
|
-
metadata?: Readonly<Record<string, unknown>>,
|
|
17
|
-
) => void;
|
|
18
|
-
|
|
19
|
-
warn: (message: string, metadata?: Readonly<Record<string, unknown>>) => void;
|
|
20
|
-
|
|
21
|
-
error: (
|
|
22
|
-
message: string,
|
|
23
|
-
metadata?: Readonly<Record<string, unknown>>,
|
|
24
|
-
) => void;
|
|
25
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { MfaSessionId } from '@/domain/mfa/value-objects/mfa-session-id.vo';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generates MFA session identifiers.
|
|
5
|
-
*
|
|
6
|
-
* Examples:
|
|
7
|
-
* - ULID
|
|
8
|
-
* - UUIDv7
|
|
9
|
-
* - KSUID
|
|
10
|
-
*
|
|
11
|
-
* Domain does NOT care.
|
|
12
|
-
*/
|
|
13
|
-
export type MfaSessionIdGenerator = {
|
|
14
|
-
generate: () => MfaSessionId;
|
|
15
|
-
};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { MfaSessionId } from '@/domain/mfa/value-objects/mfa-session-id.vo';
|
|
2
|
-
import { MFASession } from '@/domain/mfa/aggregates/mfa-session.aggregate';
|
|
3
|
-
import { IdentityId } from '@/domain';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Persistence port for MFA sessions.
|
|
7
|
-
*
|
|
8
|
-
* Implementations may use:
|
|
9
|
-
* - SQL
|
|
10
|
-
* - NoSQL
|
|
11
|
-
* - Redis
|
|
12
|
-
* - In-memory
|
|
13
|
-
*
|
|
14
|
-
* Domain MUST NOT know which.
|
|
15
|
-
*/
|
|
16
|
-
export type MfaSessionRepository = {
|
|
17
|
-
/**
|
|
18
|
-
* Find MFA session by aggregate id.
|
|
19
|
-
*/
|
|
20
|
-
findById: (id: MfaSessionId) => Promise<MFASession | null>;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Find active MFA session for an identity.
|
|
24
|
-
*/
|
|
25
|
-
findActiveByIdentity: (identityId: IdentityId) => Promise<MFASession | null>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Persist MFA session state.
|
|
29
|
-
*/
|
|
30
|
-
save: (session: MFASession) => Promise<void>;
|
|
31
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ObservabilityEvent } from '@/types/observability-event';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Observability event emitter.
|
|
5
|
-
*
|
|
6
|
-
* Used for:
|
|
7
|
-
* - audit logs
|
|
8
|
-
* - security monitoring
|
|
9
|
-
* - metrics
|
|
10
|
-
* - tracing
|
|
11
|
-
*
|
|
12
|
-
* Must be non-blocking and non-throwing.
|
|
13
|
-
*/
|
|
14
|
-
export type ObservabilityEventPort = {
|
|
15
|
-
emit: (event: ObservabilityEvent) => void;
|
|
16
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
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: AuthenticationAttempt) => Promise<void>;
|
|
10
|
-
findById: (id: string) => Promise<AuthenticationAttempt | null>;
|
|
11
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { DomainEvent } from '@rineex/ddd';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Publishes domain events emitted by aggregates.
|
|
5
|
-
*
|
|
6
|
-
* Implementations may:
|
|
7
|
-
* - dispatch to message bus
|
|
8
|
-
* - log events
|
|
9
|
-
* - forward to observability stack
|
|
10
|
-
*/
|
|
11
|
-
export type DomainEventPublisherPort = {
|
|
12
|
-
publish: (events: readonly DomainEvent[]) => Promise<void>;
|
|
13
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { SessionToken } from '@/domain/token/value-objects/session-token.vo';
|
|
2
|
-
import { SessionId } from '@/domain/session/value-objects/session-id.vo';
|
|
3
|
-
import { Session } from '@/domain/session/entities/session.entity';
|
|
4
|
-
|
|
5
|
-
export type SessionRepositoryPort = {
|
|
6
|
-
save: (session: Session) => Promise<void>;
|
|
7
|
-
findById: (id: SessionId) => Promise<Session | null>;
|
|
8
|
-
findByToken: (token: SessionToken) => Promise<Session | null>;
|
|
9
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { OauthAuthorization } from '@/domain/oauth/aggregates/oauth-authorization.aggregate';
|
|
2
|
-
|
|
3
|
-
export type OAuthAuthorizationRepository = {
|
|
4
|
-
/**
|
|
5
|
-
* Persists an OAuth authorization aggregate.
|
|
6
|
-
*/
|
|
7
|
-
save: (authorization: OauthAuthorization) => Promise<void>;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Loads authorization by its identifier.
|
|
11
|
-
*/
|
|
12
|
-
getById: (id: string) => Promise<OauthAuthorization | null>;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Finds active authorization by client and identity.
|
|
16
|
-
*/
|
|
17
|
-
findActiveByClientAndIdentity: (params: {
|
|
18
|
-
readonly clientId: string;
|
|
19
|
-
readonly identityId: string;
|
|
20
|
-
}) => Promise<OauthAuthorization | null>;
|
|
21
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export type TokenRepository = {
|
|
2
|
-
save: (token: Token) => Promise<void>;
|
|
3
|
-
|
|
4
|
-
getById: (id: string) => Promise<Token | null>;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Revokes all active tokens for an identity.
|
|
8
|
-
* Used for logout-all / security events.
|
|
9
|
-
*/
|
|
10
|
-
revokeAllByIdentity: (identityId: string) => Promise<void>;
|
|
11
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Registry for authentication method identifiers.
|
|
3
|
-
*
|
|
4
|
-
* This type is intentionally open for module augmentation.
|
|
5
|
-
* Each auth-method package extends this registry.
|
|
6
|
-
*/
|
|
7
|
-
export type AuthMethodRegistry = {
|
|
8
|
-
readonly passwordless: true;
|
|
9
|
-
readonly otp: true;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Union of all registered authentication method names.
|
|
14
|
-
*
|
|
15
|
-
* This enables:
|
|
16
|
-
* - IDE autocomplete
|
|
17
|
-
* - Type safety
|
|
18
|
-
* - Plugin-based extension
|
|
19
|
-
*/
|
|
20
|
-
export type AuthMethodName = keyof AuthMethodRegistry;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Registry of authentication policy identifiers.
|
|
3
|
-
*
|
|
4
|
-
* This registry is intentionally open for module augmentation.
|
|
5
|
-
* Each policy package extends this type.
|
|
6
|
-
*/
|
|
7
|
-
export type AuthPolicyRegistry = {
|
|
8
|
-
readonly base: true;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Union of all registered authentication policy names.
|
|
13
|
-
*
|
|
14
|
-
* Enables autocomplete and compile-time safety.
|
|
15
|
-
*/
|
|
16
|
-
export type AuthPolicyName = keyof AuthPolicyRegistry;
|
package/src/types/index.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base structure for observability events.
|
|
3
|
-
*
|
|
4
|
-
* These events:
|
|
5
|
-
* - are NOT domain events
|
|
6
|
-
* - must be safe to store long-term
|
|
7
|
-
* - must never contain secrets
|
|
8
|
-
*/
|
|
9
|
-
export type ObservabilityEventProps = {
|
|
10
|
-
readonly name: string;
|
|
11
|
-
readonly occurredAt?: Date;
|
|
12
|
-
readonly payload: Readonly<Record<string, unknown>>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export class ObservabilityEvent {
|
|
16
|
-
public readonly name: string;
|
|
17
|
-
public readonly occurredAt: Date;
|
|
18
|
-
public readonly payload: Readonly<Record<string, unknown>>;
|
|
19
|
-
|
|
20
|
-
constructor(props: ObservabilityEventProps) {
|
|
21
|
-
this.name = props.name;
|
|
22
|
-
this.occurredAt = props.occurredAt ?? new Date();
|
|
23
|
-
this.payload = props.payload;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
toPrimitives() {
|
|
27
|
-
return {
|
|
28
|
-
occurredAt: this.occurredAt.toISOString(),
|
|
29
|
-
payload: this.payload,
|
|
30
|
-
name: this.name,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Registry of risk signal identifiers.
|
|
3
|
-
*
|
|
4
|
-
* Signals are produced by detectors and consumed by policies.
|
|
5
|
-
*/
|
|
6
|
-
export type RiskSignalRegistry = {};
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Union of all registered risk signal names.
|
|
10
|
-
*/
|
|
11
|
-
export type RiskSignalName = keyof RiskSignalRegistry;
|