ofauth-shared-core 0.1.0-alpha.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.
Files changed (56) hide show
  1. package/README.md +20 -0
  2. package/dist/OfauthCore.d.ts +48 -0
  3. package/dist/OfauthCore.js +200 -0
  4. package/dist/contracts/AuthAuditContract.d.ts +25 -0
  5. package/dist/contracts/AuthAuditContract.js +16 -0
  6. package/dist/contracts/AuthErrorContract.d.ts +5 -0
  7. package/dist/contracts/AuthErrorContract.js +2 -0
  8. package/dist/contracts/AuthPolicyContract.d.ts +25 -0
  9. package/dist/contracts/AuthPolicyContract.js +2 -0
  10. package/dist/contracts/ContextContract.d.ts +27 -0
  11. package/dist/contracts/ContextContract.js +8 -0
  12. package/dist/contracts/IdentityContract.d.ts +36 -0
  13. package/dist/contracts/IdentityContract.js +2 -0
  14. package/dist/contracts/SessionContract.d.ts +25 -0
  15. package/dist/contracts/SessionContract.js +10 -0
  16. package/dist/data/applyPendingMigrations.d.ts +2 -0
  17. package/dist/data/applyPendingMigrations.js +30 -0
  18. package/dist/data/migrations.d.ts +2 -0
  19. package/dist/data/migrations.js +47 -0
  20. package/dist/data/schemas.d.ts +11 -0
  21. package/dist/data/schemas.js +109 -0
  22. package/dist/index.d.ts +20 -0
  23. package/dist/index.js +36 -0
  24. package/dist/runtime/ContractStage.d.ts +2 -0
  25. package/dist/runtime/ContractStage.js +4 -0
  26. package/dist/services/AuthAuditService.d.ts +7 -0
  27. package/dist/services/AuthAuditService.js +2 -0
  28. package/dist/services/AuthHostComposition.d.ts +40 -0
  29. package/dist/services/AuthHostComposition.js +100 -0
  30. package/dist/services/AuthPolicyService.d.ts +9 -0
  31. package/dist/services/AuthPolicyService.js +2 -0
  32. package/dist/services/ContextService.d.ts +6 -0
  33. package/dist/services/ContextService.js +2 -0
  34. package/dist/services/IdentityService.d.ts +15 -0
  35. package/dist/services/IdentityService.js +2 -0
  36. package/dist/services/SessionService.d.ts +7 -0
  37. package/dist/services/SessionService.js +2 -0
  38. package/dist/services/createContractOnlyOfauthServices.d.ts +13 -0
  39. package/dist/services/createContractOnlyOfauthServices.js +82 -0
  40. package/dist/services/createDbAdapterOfauthServices.d.ts +20 -0
  41. package/dist/services/createDbAdapterOfauthServices.js +22 -0
  42. package/dist/services/errors.d.ts +8 -0
  43. package/dist/services/errors.js +20 -0
  44. package/dist/services/impl/DbAdapterAuthAuditService.d.ts +14 -0
  45. package/dist/services/impl/DbAdapterAuthAuditService.js +107 -0
  46. package/dist/services/impl/DbAdapterAuthPolicyService.d.ts +17 -0
  47. package/dist/services/impl/DbAdapterAuthPolicyService.js +114 -0
  48. package/dist/services/impl/DbAdapterContextService.d.ts +13 -0
  49. package/dist/services/impl/DbAdapterContextService.js +79 -0
  50. package/dist/services/impl/DbAdapterIdentityService.d.ts +23 -0
  51. package/dist/services/impl/DbAdapterIdentityService.js +146 -0
  52. package/dist/services/impl/DbAdapterSessionService.d.ts +14 -0
  53. package/dist/services/impl/DbAdapterSessionService.js +63 -0
  54. package/dist/services/impl/runtimeSupport.d.ts +95 -0
  55. package/dist/services/impl/runtimeSupport.js +112 -0
  56. package/package.json +37 -0
@@ -0,0 +1,95 @@
1
+ import type { ActivityRecord, DbAdapter, LoggerAdapter, PlatformAdapter } from 'ofcore';
2
+ import type { AuthAuditEvent } from '../../contracts/AuthAuditContract';
3
+ import type { AuthPolicySnapshot } from '../../contracts/AuthPolicyContract';
4
+ import type { ContextAssignment } from '../../contracts/ContextContract';
5
+ import type { IdentityRef, IdentityStatus } from '../../contracts/IdentityContract';
6
+ import type { AssuranceLevel, SessionRef } from '../../contracts/SessionContract';
7
+ export interface IdentityRow {
8
+ id: string;
9
+ principal: string;
10
+ secretHash: string;
11
+ verifyMethod: 'pin' | 'password' | 'custom';
12
+ status: IdentityStatus;
13
+ failedAttempts: number;
14
+ lockoutUntil: string | null;
15
+ version: number;
16
+ lastModified: string;
17
+ deleted: boolean;
18
+ }
19
+ export interface AssignmentRow {
20
+ id: string;
21
+ identityId: string;
22
+ roleRef: string;
23
+ tenantId: string | null;
24
+ branchId: string | null;
25
+ scopeAttributes: Record<string, string> | null;
26
+ version: number;
27
+ lastModified: string;
28
+ deleted: boolean;
29
+ }
30
+ export interface SessionRow {
31
+ id: string;
32
+ identityId: string;
33
+ activeAssignmentId: string | null;
34
+ assuranceLevel: AssuranceLevel;
35
+ issuedAt: string;
36
+ expiresAt: string;
37
+ revokedAt: string | null;
38
+ version: number;
39
+ lastModified: string;
40
+ deleted: boolean;
41
+ }
42
+ export interface PolicyProfileRow {
43
+ id: string;
44
+ profileId: 'cashier_fast' | 'supervisor_strict' | 'member_self_service';
45
+ defaultAssuranceLevel: AssuranceLevel;
46
+ lockoutPolicyRef: string;
47
+ version: number;
48
+ lastModified: string;
49
+ deleted: boolean;
50
+ }
51
+ export interface PolicyStepUpRow {
52
+ id: string;
53
+ actionRef: string;
54
+ requiredAssuranceLevel: AssuranceLevel;
55
+ reauthWindowSeconds: number | null;
56
+ version: number;
57
+ lastModified: string;
58
+ deleted: boolean;
59
+ }
60
+ export interface AuthAuditRow {
61
+ id: string;
62
+ eventType: AuthAuditEvent['eventType'];
63
+ identityId: string | null;
64
+ sessionId: string | null;
65
+ tenantId: string | null;
66
+ branchId: string | null;
67
+ scopeAttributes: Record<string, string> | null;
68
+ result: 'success' | 'failed';
69
+ reasonCode: string | null;
70
+ timestamp: string;
71
+ syncStatus: 'pending' | 'replayed';
72
+ replayedAt: string | null;
73
+ version: number;
74
+ lastModified: string;
75
+ deleted: boolean;
76
+ }
77
+ export interface ServiceRuntimeOptions {
78
+ logger?: LoggerAdapter;
79
+ platformAdapter?: PlatformAdapter;
80
+ emitActivity?: (record: ActivityRecord) => Promise<void>;
81
+ }
82
+ export declare const DEFAULT_LOCKOUT_THRESHOLD = 5;
83
+ export declare const DEFAULT_LOCKOUT_COOLDOWN_SECONDS: number;
84
+ export declare const DEFAULT_SESSION_TTL_SECONDS: number;
85
+ export declare function nowIso(): string;
86
+ export declare function plusSecondsIso(baseIso: string, seconds: number): string;
87
+ export declare function isPast(iso: string): boolean;
88
+ export declare function makeIdFactory(prefix: string): () => string;
89
+ export declare function toIdentityRef(row: IdentityRow): IdentityRef;
90
+ export declare function toAssignment(row: AssignmentRow): ContextAssignment;
91
+ export declare function toSessionRef(row: SessionRow, assignment?: AssignmentRow | null): SessionRef;
92
+ export declare function verifySecret(platformAdapter: PlatformAdapter | undefined, plainSecret: string, secretHash: string): Promise<boolean>;
93
+ export declare function emitAuthActivity(options: ServiceRuntimeOptions, event: AuthAuditEvent): Promise<void>;
94
+ export declare function getAssignmentById(db: DbAdapter, id: string | null): Promise<AssignmentRow | null>;
95
+ export declare function fallbackPolicyProfiles(): AuthPolicySnapshot['profiles'];
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_SESSION_TTL_SECONDS = exports.DEFAULT_LOCKOUT_COOLDOWN_SECONDS = exports.DEFAULT_LOCKOUT_THRESHOLD = void 0;
4
+ exports.nowIso = nowIso;
5
+ exports.plusSecondsIso = plusSecondsIso;
6
+ exports.isPast = isPast;
7
+ exports.makeIdFactory = makeIdFactory;
8
+ exports.toIdentityRef = toIdentityRef;
9
+ exports.toAssignment = toAssignment;
10
+ exports.toSessionRef = toSessionRef;
11
+ exports.verifySecret = verifySecret;
12
+ exports.emitAuthActivity = emitAuthActivity;
13
+ exports.getAssignmentById = getAssignmentById;
14
+ exports.fallbackPolicyProfiles = fallbackPolicyProfiles;
15
+ const schemas_1 = require("../../data/schemas");
16
+ exports.DEFAULT_LOCKOUT_THRESHOLD = 5;
17
+ exports.DEFAULT_LOCKOUT_COOLDOWN_SECONDS = 15 * 60;
18
+ exports.DEFAULT_SESSION_TTL_SECONDS = 8 * 60 * 60;
19
+ function nowIso() {
20
+ return new Date().toISOString();
21
+ }
22
+ function plusSecondsIso(baseIso, seconds) {
23
+ return new Date(new Date(baseIso).getTime() + seconds * 1000).toISOString();
24
+ }
25
+ function isPast(iso) {
26
+ return new Date(iso).getTime() <= Date.now();
27
+ }
28
+ function makeIdFactory(prefix) {
29
+ let counter = 0;
30
+ return () => {
31
+ counter += 1;
32
+ return `${prefix}-${Date.now()}-${counter}`;
33
+ };
34
+ }
35
+ function toIdentityRef(row) {
36
+ return {
37
+ identityId: row.id,
38
+ principal: row.principal,
39
+ status: row.status,
40
+ };
41
+ }
42
+ function toAssignment(row) {
43
+ return {
44
+ assignmentId: row.id,
45
+ identityId: row.identityId,
46
+ roleRef: row.roleRef,
47
+ scopeRef: {
48
+ ...(row.tenantId ? { tenantId: row.tenantId } : {}),
49
+ ...(row.branchId ? { branchId: row.branchId } : {}),
50
+ ...(row.scopeAttributes ? { attributes: row.scopeAttributes } : {}),
51
+ },
52
+ };
53
+ }
54
+ function toSessionRef(row, assignment) {
55
+ return {
56
+ sessionId: row.id,
57
+ identityId: row.identityId,
58
+ activeScopeRef: assignment
59
+ ? {
60
+ ...(assignment.tenantId ? { tenantId: assignment.tenantId } : {}),
61
+ ...(assignment.branchId ? { branchId: assignment.branchId } : {}),
62
+ ...(assignment.scopeAttributes ? { attributes: assignment.scopeAttributes } : {}),
63
+ }
64
+ : undefined,
65
+ assuranceLevel: row.assuranceLevel,
66
+ issuedAt: row.issuedAt,
67
+ expiresAt: row.expiresAt,
68
+ };
69
+ }
70
+ async function verifySecret(platformAdapter, plainSecret, secretHash) {
71
+ if (platformAdapter) {
72
+ return platformAdapter.verifyPin(plainSecret, secretHash);
73
+ }
74
+ return plainSecret === secretHash;
75
+ }
76
+ async function emitAuthActivity(options, event) {
77
+ if (!options.emitActivity)
78
+ return;
79
+ await options.emitActivity({
80
+ activityId: event.eventId,
81
+ activityType: `ofauth.${event.eventType.toLowerCase()}`,
82
+ occurredAt: event.timestamp,
83
+ scopeRef: {
84
+ domain: 'ofauth',
85
+ ...(event.scopeRef?.tenantId ? { tenantId: event.scopeRef.tenantId } : {}),
86
+ ...(event.scopeRef?.branchId ? { branchId: event.scopeRef.branchId } : {}),
87
+ },
88
+ actor: event.identityId ? { userId: event.identityId } : undefined,
89
+ payload: {
90
+ eventType: event.eventType,
91
+ result: event.result,
92
+ reasonCode: event.reasonCode ?? null,
93
+ sessionId: event.sessionId ?? null,
94
+ scopeAttributes: event.scopeRef?.attributes ?? null,
95
+ },
96
+ });
97
+ }
98
+ async function getAssignmentById(db, id) {
99
+ if (!id)
100
+ return null;
101
+ const row = await db.get(schemas_1.OFAUTH_TABLES.assignments, id);
102
+ if (!row || row.deleted)
103
+ return null;
104
+ return row;
105
+ }
106
+ function fallbackPolicyProfiles() {
107
+ return [
108
+ { profileId: 'cashier_fast', defaultAssuranceLevel: 'basic', lockoutPolicyRef: 'default' },
109
+ { profileId: 'supervisor_strict', defaultAssuranceLevel: 'elevated', lockoutPolicyRef: 'strict' },
110
+ { profileId: 'member_self_service', defaultAssuranceLevel: 'basic', lockoutPolicyRef: 'member' },
111
+ ];
112
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "ofauth-shared-core",
3
+ "version": "0.1.0-alpha.0",
4
+ "private": false,
5
+ "description": "Offline-first auth shared-core (identity/session/context/assurance) for of* domain modules.",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
13
+ "build": "npm run clean && tsc -p tsconfig.build.json",
14
+ "typecheck": "tsc -p tsconfig.json --noEmit",
15
+ "test": "NODE_PATH=.. npm run build && NODE_PATH=.. node --test ./tests/*.test.js",
16
+ "verify:contract": "node ./scripts/verify-surface.js",
17
+ "verify:surface": "node ./scripts/verify-surface.js",
18
+ "verify:logic": "NODE_PATH=.. npm run build && NODE_PATH=.. node ./scripts/verify-logic.js",
19
+ "verify:factory-boundary": "node ./scripts/verify-no-service-logic-in-factory.js",
20
+ "ci:check": "npm run typecheck && npm run verify:contract && npm run test && npm run verify:logic && npm run verify:factory-boundary",
21
+ "prepublishOnly": "npm run ci:check",
22
+ "prepack": "npm run build"
23
+ },
24
+ "dependencies": {
25
+ "ofcore": "0.1.0-alpha.0"
26
+ },
27
+ "devDependencies": {
28
+ "typescript": "^5.9.3"
29
+ },
30
+ "author": {
31
+ "name": "Agus Made",
32
+ "email": "krisnaparta@gmail.com"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ }
37
+ }