@happyvertical/smrt-profiles 0.51.32 → 0.51.34
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/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/agent-profile.d.ts +71 -0
- package/dist/agent-profile.d.ts.map +1 -0
- package/dist/auth/index.d.ts +12 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/magicLinkService.d.ts +79 -0
- package/dist/auth/magicLinkService.d.ts.map +1 -0
- package/dist/auth/nip05Handler.d.ts +73 -0
- package/dist/auth/nip05Handler.d.ts.map +1 -0
- package/dist/auth/normalizeIdentityEmail.d.ts +8 -0
- package/dist/auth/normalizeIdentityEmail.d.ts.map +1 -0
- package/dist/auth/nostrCrypto.d.ts +111 -0
- package/dist/auth/nostrCrypto.d.ts.map +1 -0
- package/dist/auth/oidcProvisioningCoordinator.d.ts +58 -0
- package/dist/auth/oidcProvisioningCoordinator.d.ts.map +1 -0
- package/dist/auth/oidcProvisioningPrimitives.d.ts +23 -0
- package/dist/auth/oidcProvisioningPrimitives.d.ts.map +1 -0
- package/dist/auth/resolveIdentity.d.ts +188 -0
- package/dist/auth/resolveIdentity.d.ts.map +1 -0
- package/dist/collections/ApiKeyCollection.d.ts +46 -0
- package/dist/collections/ApiKeyCollection.d.ts.map +1 -0
- package/dist/collections/AuditLogCollection.d.ts +50 -0
- package/dist/collections/AuditLogCollection.d.ts.map +1 -0
- package/dist/collections/MagicLinkTokenCollection.d.ts +58 -0
- package/dist/collections/MagicLinkTokenCollection.d.ts.map +1 -0
- package/dist/collections/NostrIdentityCollection.d.ts +66 -0
- package/dist/collections/NostrIdentityCollection.d.ts.map +1 -0
- package/dist/collections/OidcIdentityCollection.d.ts +45 -0
- package/dist/collections/OidcIdentityCollection.d.ts.map +1 -0
- package/dist/collections/OidcProfileEmailReservationCollection.d.ts +7 -0
- package/dist/collections/OidcProfileEmailReservationCollection.d.ts.map +1 -0
- package/dist/collections/ProfileAssetCollection.d.ts +17 -0
- package/dist/collections/ProfileAssetCollection.d.ts.map +1 -0
- package/dist/collections/ProfileCollection.d.ts +130 -0
- package/dist/collections/ProfileCollection.d.ts.map +1 -0
- package/dist/collections/ProfileMetadataCollection.d.ts +33 -0
- package/dist/collections/ProfileMetadataCollection.d.ts.map +1 -0
- package/dist/collections/ProfileMetafieldCollection.d.ts +31 -0
- package/dist/collections/ProfileMetafieldCollection.d.ts.map +1 -0
- package/dist/collections/ProfileRelationshipCollection.d.ts +44 -0
- package/dist/collections/ProfileRelationshipCollection.d.ts.map +1 -0
- package/dist/collections/ProfileRelationshipTermCollection.d.ts +32 -0
- package/dist/collections/ProfileRelationshipTermCollection.d.ts.map +1 -0
- package/dist/collections/ProfileRelationshipTypeCollection.d.ts +41 -0
- package/dist/collections/ProfileRelationshipTypeCollection.d.ts.map +1 -0
- package/dist/collections/ProfileTypeCollection.d.ts +40 -0
- package/dist/collections/ProfileTypeCollection.d.ts.map +1 -0
- package/dist/collections/index.d.ts +18 -0
- package/dist/collections/index.d.ts.map +1 -0
- package/dist/index.d.ts +55 -2059
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -1
- package/dist/internal/oidc-provisioning.d.ts +14 -119
- package/dist/internal/oidc-provisioning.d.ts.map +1 -0
- package/dist/manifest.json +1 -1
- package/dist/migrations/backfillProfileEmailKeys.d.ts +16 -0
- package/dist/migrations/backfillProfileEmailKeys.d.ts.map +1 -0
- package/dist/models/ApiKey.d.ts +94 -0
- package/dist/models/ApiKey.d.ts.map +1 -0
- package/dist/models/AuditLog.d.ts +71 -0
- package/dist/models/AuditLog.d.ts.map +1 -0
- package/dist/models/MagicLinkToken.d.ts +104 -0
- package/dist/models/MagicLinkToken.d.ts.map +1 -0
- package/dist/models/NostrIdentity.d.ts +112 -0
- package/dist/models/NostrIdentity.d.ts.map +1 -0
- package/dist/models/OidcIdentity.d.ts +82 -0
- package/dist/models/OidcIdentity.d.ts.map +1 -0
- package/dist/models/OidcProfileEmailReservation.d.ts +12 -0
- package/dist/models/OidcProfileEmailReservation.d.ts.map +1 -0
- package/dist/models/Profile.d.ts +243 -0
- package/dist/models/Profile.d.ts.map +1 -0
- package/dist/models/ProfileAsset.d.ts +18 -0
- package/dist/models/ProfileAsset.d.ts.map +1 -0
- package/dist/models/ProfileMetadata.d.ts +33 -0
- package/dist/models/ProfileMetadata.d.ts.map +1 -0
- package/dist/models/ProfileMetafield.d.ts +62 -0
- package/dist/models/ProfileMetafield.d.ts.map +1 -0
- package/dist/models/ProfileRelationship.d.ts +56 -0
- package/dist/models/ProfileRelationship.d.ts.map +1 -0
- package/dist/models/ProfileRelationshipTerm.d.ts +37 -0
- package/dist/models/ProfileRelationshipTerm.d.ts.map +1 -0
- package/dist/models/ProfileRelationshipType.d.ts +59 -0
- package/dist/models/ProfileRelationshipType.d.ts.map +1 -0
- package/dist/models/ProfileType.d.ts +27 -0
- package/dist/models/ProfileType.d.ts.map +1 -0
- package/dist/models/ProfileTypes.d.ts +32 -0
- package/dist/models/ProfileTypes.d.ts.map +1 -0
- package/dist/models/index.d.ts +18 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/prompts.d.ts +17 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +4 -4
- package/dist/testing/oidcProvisioningDecisionMatrix.d.ts +1168 -0
- package/dist/testing/oidcProvisioningDecisionMatrix.d.ts.map +1 -0
- package/dist/types.d.ts +33 -732
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +52 -817
- package/dist/utils.d.ts.map +1 -0
- package/package.json +7 -7
|
@@ -1,122 +1,17 @@
|
|
|
1
|
-
import { getDatabase } from '@happyvertical/sql';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Root adapters must expose `beginTransaction`. Already-bound adapters must
|
|
7
|
-
* support savepoints. An adapter that exposes only `transaction()` is
|
|
8
|
-
* intentionally ambiguous and fails closed instead of risking a nested
|
|
9
|
-
* transaction that could roll back its caller's work.
|
|
10
|
-
*/
|
|
11
|
-
export declare function coordinateOidcProvisioning<T>(options: OidcProvisioningCoordinatorOptions<T>): Promise<T>;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Trusted integration surface for framework packages participating in the
|
|
15
|
-
* owner-aware OIDC provisioning transaction.
|
|
16
|
-
*
|
|
17
|
-
* Application code should use UserCollection.getOrCreateFromOidc() instead.
|
|
18
|
-
* The generic result avoids duplicating nominal SMRT model declarations across
|
|
19
|
-
* package entry bundles; trusted callers bind it to the root package model.
|
|
20
|
-
*/
|
|
21
|
-
export declare function createOidcProvisioningPerson<TProfile>(db: DatabaseInterface, input: OidcProvisioningPersonInput): Promise<TProfile>;
|
|
22
|
-
|
|
23
|
-
declare type DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;
|
|
24
|
-
|
|
25
|
-
declare type DatabaseInterface_2 = Awaited<ReturnType<typeof getDatabase>>;
|
|
26
|
-
|
|
27
|
-
/** Trusted integration insert after the caller proves Profile ownership. */
|
|
28
|
-
export declare function insertOidcProvisioningIdentity<TIdentity>(db: DatabaseInterface, input: OidcProvisioningIdentityInput): Promise<TIdentity>;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Detect an adapter error caused by an aborted transaction.
|
|
32
|
-
*
|
|
33
|
-
* Reduced to the framework contract in #2366. The heuristic this replaced
|
|
34
|
-
* matched a bare `/transaction.*aborted/` against every message in the chain,
|
|
35
|
-
* which would misclassify a genuine foreign-key or check violation whose text
|
|
36
|
-
* happened to mention a transaction. Core now recognizes PostgreSQL's
|
|
37
|
-
* `25P02 in_failed_sql_transaction` from the driver's own SQLSTATE, whichever
|
|
38
|
-
* layer wrapped it.
|
|
39
|
-
*
|
|
40
|
-
* Kept as a named export because it is part of this package's provisioning
|
|
41
|
-
* API surface; the body is now a single delegation.
|
|
42
|
-
*/
|
|
43
|
-
export declare function isOidcAbortedTransactionError(error: unknown): boolean;
|
|
44
|
-
|
|
45
|
-
/** Classify only the durable constraints used to converge OIDC retries. */
|
|
46
|
-
export declare function isOidcProvisioningRaceConflict(error: unknown, options?: OidcProvisioningRaceClassifierOptions): boolean;
|
|
47
|
-
|
|
48
|
-
/** Shared transaction and concurrency policy for OIDC provisioning. */
|
|
49
|
-
export declare interface OidcProvisioningCoordinatorOptions<T> {
|
|
50
|
-
/** Root or transaction-bound database used for every provisioning write. */
|
|
51
|
-
db: DatabaseInterface_2;
|
|
52
|
-
/**
|
|
53
|
-
* Stable keys used for local serialization. Supply both the exact
|
|
54
|
-
* issuer/subject key and normalized email when available.
|
|
55
|
-
*/
|
|
56
|
-
lockKeys: readonly string[];
|
|
57
|
-
/** Package-specific durable race-arbiter classifier. */
|
|
58
|
-
isRaceConflict: (error: unknown) => boolean;
|
|
59
|
-
/** Package-specific transaction failure mapping. */
|
|
60
|
-
createTransactionError: (message: string, cause?: unknown) => Error;
|
|
61
|
-
/** Package-specific terminal concurrency failure mapping. */
|
|
62
|
-
createConcurrencyError: (cause?: unknown) => Error;
|
|
63
|
-
/** Provision atomically using the supplied transaction-bound handle. */
|
|
64
|
-
provision: (tx: DatabaseInterface_2) => Promise<T>;
|
|
65
|
-
/**
|
|
66
|
-
* Rehydrate root-owned results after commit so models do not retain a
|
|
67
|
-
* released transaction client. Omit for non-model results.
|
|
68
|
-
*/
|
|
69
|
-
rebindRootResult?: (result: T, rootDb: DatabaseInterface_2) => Promise<T>;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export declare interface OidcProvisioningIdentityInput {
|
|
73
|
-
email?: string;
|
|
74
|
-
issuer: string;
|
|
75
|
-
profileId: string;
|
|
76
|
-
provider: string;
|
|
77
|
-
subject: string;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export declare interface OidcProvisioningPersonInput {
|
|
81
|
-
email?: string;
|
|
82
|
-
name?: string;
|
|
83
|
-
preferredUsername?: string;
|
|
84
|
-
subject: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export declare interface OidcProvisioningRaceClassifierOptions {
|
|
88
|
-
/** Package-specific database constraint messages. */
|
|
89
|
-
messagePatterns?: readonly RegExp[];
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Wrap a known OIDC arbiter write so only its unique failure is retryable. */
|
|
93
|
-
export declare function saveOidcRaceArbiter<T>(operation: () => Promise<T>): Promise<T>;
|
|
94
|
-
|
|
95
|
-
export { }
|
|
96
|
-
|
|
97
|
-
|
|
1
|
+
import type { getDatabase } from '@happyvertical/sql';
|
|
2
|
+
export { coordinateOidcProvisioning, isOidcAbortedTransactionError, isOidcProvisioningRaceConflict, type OidcProvisioningCoordinatorOptions, type OidcProvisioningRaceClassifierOptions, saveOidcRaceArbiter, } from '../auth/oidcProvisioningCoordinator.js';
|
|
3
|
+
import { type OidcProvisioningIdentityInput, type OidcProvisioningPersonInput } from '../auth/oidcProvisioningPrimitives';
|
|
4
|
+
type DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;
|
|
5
|
+
export type { OidcProvisioningIdentityInput, OidcProvisioningPersonInput };
|
|
98
6
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* which is critical in monorepos where the same package can be loaded
|
|
102
|
-
* from different paths (e.g., pnpm store vs workspace symlink).
|
|
7
|
+
* Trusted integration surface for framework packages participating in the
|
|
8
|
+
* owner-aware OIDC provisioning transaction.
|
|
103
9
|
*
|
|
104
|
-
*
|
|
10
|
+
* Application code should use UserCollection.getOrCreateFromOidc() instead.
|
|
11
|
+
* The generic result avoids duplicating nominal SMRT model declarations across
|
|
12
|
+
* package entry bundles; trusted callers bind it to the root package model.
|
|
105
13
|
*/
|
|
106
|
-
declare
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Extend globalThis to include custom validators registry.
|
|
114
|
-
* Using globalThis ensures all module instances share the same validators,
|
|
115
|
-
* which is critical in monorepos where the same package can be loaded
|
|
116
|
-
* from different paths (e.g., pnpm store vs workspace symlink).
|
|
117
|
-
*
|
|
118
|
-
* @see https://github.com/happyvertical/smrt/issues/543
|
|
119
|
-
*/
|
|
120
|
-
declare global {
|
|
121
|
-
var __smrtProfileMetafieldValidators: Map<string, ValidatorFunction> | undefined;
|
|
122
|
-
}
|
|
14
|
+
export declare function createOidcProvisioningPerson<TProfile>(db: DatabaseInterface, input: OidcProvisioningPersonInput): Promise<TProfile>;
|
|
15
|
+
/** Trusted integration insert after the caller proves Profile ownership. */
|
|
16
|
+
export declare function insertOidcProvisioningIdentity<TIdentity>(db: DatabaseInterface, input: OidcProvisioningIdentityInput): Promise<TIdentity>;
|
|
17
|
+
//# sourceMappingURL=oidc-provisioning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-provisioning.d.ts","sourceRoot":"","sources":["../../src/internal/oidc-provisioning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,8BAA8B,EAC9B,KAAK,kCAAkC,EACvC,KAAK,qCAAqC,EAC1C,mBAAmB,GACpB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAGL,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EACjC,MAAM,oCAAoC,CAAC;AAE5C,KAAK,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC;AAEjE,YAAY,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,CAAC;AAE3E;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAAC,QAAQ,EACzD,EAAE,EAAE,iBAAiB,EACrB,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,QAAQ,CAAC,CAEnB;AAED,4EAA4E;AAC5E,wBAAsB,8BAA8B,CAAC,SAAS,EAC5D,EAAE,EAAE,iBAAiB,EACrB,KAAK,EAAE,6BAA6B,GACnC,OAAO,CAAC,SAAS,CAAC,CAEpB"}
|
package/dist/manifest.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { getDatabase } from '@happyvertical/sql';
|
|
2
|
+
type DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;
|
|
3
|
+
export declare const PROFILE_EMAIL_KEY_BACKFILL_NAME = "@happyvertical/smrt-profiles:profile-email-keys:v1";
|
|
4
|
+
export interface BackfillProfileEmailKeysResult {
|
|
5
|
+
updated: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Populate adapter-independent Profile email keys after the schema migration.
|
|
9
|
+
*
|
|
10
|
+
* Run this from one deploy process after legacy writers are stopped or
|
|
11
|
+
* upgraded. Every read and update runs in one transaction, and repeats are a
|
|
12
|
+
* no-op.
|
|
13
|
+
*/
|
|
14
|
+
export declare function backfillProfileEmailKeys(db: DatabaseInterface): Promise<BackfillProfileEmailKeysResult>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=backfillProfileEmailKeys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backfillProfileEmailKeys.d.ts","sourceRoot":"","sources":["../../src/migrations/backfillProfileEmailKeys.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,KAAK,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC;AAEjE,eAAO,MAAM,+BAA+B,uDACU,CAAC;AAEvD,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,iBAAiB,GACpB,OAAO,CAAC,8BAA8B,CAAC,CAiDzC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApiKey - API keys for CLI and CI authentication
|
|
3
|
+
*
|
|
4
|
+
* Provides secure API key management with hashing, scopes, and expiration.
|
|
5
|
+
* Keys are stored as hashes - the plaintext is only returned on creation.
|
|
6
|
+
*/
|
|
7
|
+
import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
8
|
+
import type { Profile } from './Profile';
|
|
9
|
+
export interface ApiKeyOptions extends SmrtObjectOptions {
|
|
10
|
+
profileId?: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
scopes?: string[];
|
|
13
|
+
expiresAt?: Date | null;
|
|
14
|
+
}
|
|
15
|
+
export interface GenerateKeyResult {
|
|
16
|
+
key: string;
|
|
17
|
+
apiKey: ApiKey;
|
|
18
|
+
}
|
|
19
|
+
export declare class ApiKey extends SmrtObject {
|
|
20
|
+
/**
|
|
21
|
+
* Link to the Profile (Person, Organization, Bot)
|
|
22
|
+
*/
|
|
23
|
+
profileId?: string;
|
|
24
|
+
/**
|
|
25
|
+
* SHA-256 hash of the API key.
|
|
26
|
+
*
|
|
27
|
+
* Indexed: `verify()` looks keys up by this hash on every authenticated
|
|
28
|
+
* request (#2364, epic #2382 finding A3).
|
|
29
|
+
*/
|
|
30
|
+
keyHash: string;
|
|
31
|
+
/**
|
|
32
|
+
* First 8 characters of the key for identification (e.g., "sk_live_a1b2...")
|
|
33
|
+
*/
|
|
34
|
+
keyPrefix: string;
|
|
35
|
+
/**
|
|
36
|
+
* Human-readable name for the key (e.g., "CI Bot", "Local CLI")
|
|
37
|
+
*/
|
|
38
|
+
name: string;
|
|
39
|
+
/**
|
|
40
|
+
* Scopes/permissions for this key
|
|
41
|
+
*/
|
|
42
|
+
scopes: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Last time this key was used
|
|
45
|
+
*/
|
|
46
|
+
lastUsedAt: Date | null;
|
|
47
|
+
/**
|
|
48
|
+
* When this key expires (null = never)
|
|
49
|
+
*/
|
|
50
|
+
expiresAt: Date | null;
|
|
51
|
+
/**
|
|
52
|
+
* When this key was revoked (null = active)
|
|
53
|
+
*/
|
|
54
|
+
revokedAt: Date | null;
|
|
55
|
+
constructor(options?: ApiKeyOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Get the linked Profile
|
|
58
|
+
*/
|
|
59
|
+
getProfile(): Promise<Profile | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Check if this key is valid (not expired, not revoked)
|
|
62
|
+
*/
|
|
63
|
+
isValid(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Check if this key has a specific scope
|
|
66
|
+
*/
|
|
67
|
+
hasScope(scope: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Revoke this key
|
|
70
|
+
*/
|
|
71
|
+
revoke(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Record usage of this key
|
|
74
|
+
*/
|
|
75
|
+
recordUsage(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Hash an API key
|
|
78
|
+
*/
|
|
79
|
+
static hashKey(key: string): string;
|
|
80
|
+
/**
|
|
81
|
+
* Generate a new API key for a profile
|
|
82
|
+
*/
|
|
83
|
+
static generate(profile: Profile, options: {
|
|
84
|
+
name: string;
|
|
85
|
+
scopes?: string[];
|
|
86
|
+
expiresAt?: Date | null;
|
|
87
|
+
db?: SmrtObjectOptions['db'];
|
|
88
|
+
}): Promise<GenerateKeyResult>;
|
|
89
|
+
/**
|
|
90
|
+
* Verify an API key and return the ApiKey record if valid
|
|
91
|
+
*/
|
|
92
|
+
static verify(key: string, options?: SmrtObjectOptions): Promise<ApiKey | null>;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=ApiKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiKey.d.ts","sourceRoot":"","sources":["../../src/models/ApiKey.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAUa,MAAO,SAAQ,UAAU;IACpC;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;OAKG;IAEH,OAAO,EAAE,MAAM,CAAM;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAM;IAElB;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAM;IAEtB;;OAEG;IACH,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE9B;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;gBAElB,OAAO,GAAE,aAAkB;IAQvC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI3C;;OAEG;IACH,OAAO,IAAI,OAAO;IAMlB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBlC;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAInC;;OAEG;WACU,QAAQ,CACnB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;QACxB,EAAE,CAAC,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;KAC9B,GACA,OAAO,CAAC,iBAAiB,CAAC;IAuB7B;;OAEG;WACU,MAAM,CACjB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAwB1B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuditLog - Tracks all actions for full audit trail
|
|
3
|
+
*
|
|
4
|
+
* Records who did what, when, and how (web, CLI, CI, webhook, MCP).
|
|
5
|
+
* Supports pass-through identity for CI workflows.
|
|
6
|
+
*/
|
|
7
|
+
import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
8
|
+
import type { Profile } from './Profile';
|
|
9
|
+
export type AuditSource = 'web' | 'cli' | 'ci' | 'webhook' | 'mcp';
|
|
10
|
+
export interface AuditLogOptions extends SmrtObjectOptions {
|
|
11
|
+
profileId?: string;
|
|
12
|
+
action?: string;
|
|
13
|
+
resourceType?: string;
|
|
14
|
+
resourceId?: string;
|
|
15
|
+
source?: AuditSource;
|
|
16
|
+
metadata?: Record<string, unknown>;
|
|
17
|
+
onBehalfOfId?: string | null;
|
|
18
|
+
tenantId?: string | null;
|
|
19
|
+
}
|
|
20
|
+
export declare class AuditLog extends SmrtObject {
|
|
21
|
+
tenantId: string | null;
|
|
22
|
+
/**
|
|
23
|
+
* The profile who performed the action
|
|
24
|
+
*/
|
|
25
|
+
profileId?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Action performed (e.g., 'issue.update', 'feedback.incorporate')
|
|
28
|
+
*/
|
|
29
|
+
action: string;
|
|
30
|
+
/**
|
|
31
|
+
* Type of resource affected (e.g., 'Issue', 'Repository')
|
|
32
|
+
*/
|
|
33
|
+
resourceType: string;
|
|
34
|
+
/**
|
|
35
|
+
* ID of the affected resource
|
|
36
|
+
*/
|
|
37
|
+
resourceId: string;
|
|
38
|
+
/**
|
|
39
|
+
* Source of the action
|
|
40
|
+
*/
|
|
41
|
+
source: AuditSource;
|
|
42
|
+
/**
|
|
43
|
+
* Additional context (CI run ID, request ID, etc.)
|
|
44
|
+
*/
|
|
45
|
+
metadata: Record<string, unknown>;
|
|
46
|
+
/**
|
|
47
|
+
* For pass-through identity in CI - the actual person who triggered
|
|
48
|
+
*/
|
|
49
|
+
onBehalfOfId?: string | null;
|
|
50
|
+
constructor(options?: AuditLogOptions);
|
|
51
|
+
/**
|
|
52
|
+
* Get the profile who performed the action
|
|
53
|
+
*/
|
|
54
|
+
getProfile(): Promise<Profile | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Get the profile on whose behalf the action was performed (if any)
|
|
57
|
+
*/
|
|
58
|
+
getOnBehalfOf(): Promise<Profile | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Get the effective actor (onBehalfOf if set, otherwise profile)
|
|
61
|
+
*/
|
|
62
|
+
getEffectiveActor(): Promise<Profile | null>;
|
|
63
|
+
/**
|
|
64
|
+
* Create an audit log entry
|
|
65
|
+
*/
|
|
66
|
+
static record(options: AuditLogOptions & {
|
|
67
|
+
profile: Profile;
|
|
68
|
+
onBehalfOf?: Profile | null;
|
|
69
|
+
}): Promise<AuditLog>;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=AuditLog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditLog.d.ts","sourceRoot":"","sources":["../../src/models/AuditLog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAEL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC;AAEnE,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,qBAOa,QAAS,SAAQ,UAAU;IAEtC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAM;IAEpB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAM;IAE1B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,MAAM,EAAE,WAAW,CAAS;IAE5B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;IAEvC;;OAEG;IAEH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEjB,OAAO,GAAE,eAAoB;IAYzC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI3C;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAK9C;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAMlD;;OAEG;WACU,MAAM,CACjB,OAAO,EAAE,eAAe,GAAG;QACzB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;KAC7B,GACA,OAAO,CAAC,QAAQ,CAAC;CAUrB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MagicLinkToken - Temporary tokens for email verification
|
|
3
|
+
*
|
|
4
|
+
* Stores hashed magic link tokens with expiration. Tokens are single-use
|
|
5
|
+
* and automatically invalidated after verification or expiration.
|
|
6
|
+
*/
|
|
7
|
+
import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
8
|
+
import type { NostrIdentity } from './NostrIdentity';
|
|
9
|
+
export interface MagicLinkTokenOptions extends SmrtObjectOptions {
|
|
10
|
+
nostrIdentityId?: string;
|
|
11
|
+
tokenHash?: string;
|
|
12
|
+
email?: string;
|
|
13
|
+
expiresAt?: Date;
|
|
14
|
+
usedAt?: Date | null;
|
|
15
|
+
requestedFromIp?: string;
|
|
16
|
+
createdAt?: Date;
|
|
17
|
+
}
|
|
18
|
+
export interface GenerateTokenResult {
|
|
19
|
+
/** The plaintext token (only available at creation time) */
|
|
20
|
+
token: string;
|
|
21
|
+
/** The MagicLinkToken record */
|
|
22
|
+
magicLinkToken: MagicLinkToken;
|
|
23
|
+
}
|
|
24
|
+
export declare class MagicLinkToken extends SmrtObject {
|
|
25
|
+
/**
|
|
26
|
+
* Link to the NostrIdentity this token is for
|
|
27
|
+
*/
|
|
28
|
+
nostrIdentityId?: string;
|
|
29
|
+
/**
|
|
30
|
+
* SHA-256 hash of the token (never store plaintext).
|
|
31
|
+
*
|
|
32
|
+
* Indexed: `verify()` looks tokens up by this hash on every magic-link
|
|
33
|
+
* click (#2364, epic #2382 finding A3).
|
|
34
|
+
*/
|
|
35
|
+
tokenHash: string;
|
|
36
|
+
/**
|
|
37
|
+
* Email this token was sent to
|
|
38
|
+
*/
|
|
39
|
+
email: string;
|
|
40
|
+
/**
|
|
41
|
+
* When this token expires
|
|
42
|
+
*/
|
|
43
|
+
expiresAt: Date;
|
|
44
|
+
/**
|
|
45
|
+
* When this token was used (null = unused)
|
|
46
|
+
*/
|
|
47
|
+
usedAt: Date | null;
|
|
48
|
+
/**
|
|
49
|
+
* IP address that requested the token (for rate limiting)
|
|
50
|
+
*/
|
|
51
|
+
requestedFromIp: string;
|
|
52
|
+
/**
|
|
53
|
+
* When this token was created (for rate limiting)
|
|
54
|
+
*/
|
|
55
|
+
createdAt: Date;
|
|
56
|
+
constructor(options?: MagicLinkTokenOptions);
|
|
57
|
+
/**
|
|
58
|
+
* Hash a token using SHA-256
|
|
59
|
+
*/
|
|
60
|
+
static hashToken(token: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Generate a new magic link token
|
|
63
|
+
* @param nostrIdentity - The identity this token is for
|
|
64
|
+
* @param email - The email address to send to
|
|
65
|
+
* @param options - Additional options
|
|
66
|
+
*/
|
|
67
|
+
static generate(nostrIdentity: NostrIdentity, email: string, options?: {
|
|
68
|
+
expiresInMinutes?: number;
|
|
69
|
+
requestedFromIp?: string;
|
|
70
|
+
db?: SmrtObjectOptions['db'];
|
|
71
|
+
}): Promise<GenerateTokenResult>;
|
|
72
|
+
/**
|
|
73
|
+
* Verify a token and return the MagicLinkToken if valid
|
|
74
|
+
* @param token - The plaintext token to verify
|
|
75
|
+
* @param options - Database options
|
|
76
|
+
* @returns The MagicLinkToken if valid, null otherwise
|
|
77
|
+
*/
|
|
78
|
+
static verify(token: string, options?: SmrtObjectOptions): Promise<MagicLinkToken | null>;
|
|
79
|
+
/**
|
|
80
|
+
* Check if this token is valid (not expired and not used)
|
|
81
|
+
*/
|
|
82
|
+
isValid(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Check if this token has expired
|
|
85
|
+
*/
|
|
86
|
+
isExpired(): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Check if this token has been used
|
|
89
|
+
*/
|
|
90
|
+
isUsed(): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Mark this token as used
|
|
93
|
+
*/
|
|
94
|
+
markUsed(): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Get the NostrIdentity this token is for
|
|
97
|
+
*/
|
|
98
|
+
getNostrIdentity(): Promise<NostrIdentity | null>;
|
|
99
|
+
/**
|
|
100
|
+
* Get time remaining until expiration in seconds
|
|
101
|
+
*/
|
|
102
|
+
getTimeRemainingSeconds(): number;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=MagicLinkToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MagicLinkToken.d.ts","sourceRoot":"","sources":["../../src/models/MagicLinkToken.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,cAAc,EAAE,cAAc,CAAC;CAChC;AAKD,qBASa,cAAe,SAAQ,UAAU;IAC5C;;OAEG;IAEH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;OAKG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;IAEnB;;OAEG;IACH,SAAS,EAAE,IAAI,CAEb;IAEF;;OAEG;IACH,MAAM,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE3B;;OAEG;IACH,eAAe,EAAE,MAAM,CAAM;IAE7B;;OAEG;IACH,SAAS,EAAE,IAAI,CAAc;gBAEjB,OAAO,GAAE,qBAA0B;IAW/C;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIvC;;;;;OAKG;WACU,QAAQ,CACnB,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QACP,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,EAAE,CAAC,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;KACzB,GACL,OAAO,CAAC,mBAAmB,CAAC;IAyB/B;;;;;OAKG;WACU,MAAM,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAwBjC;;OAEG;IACH,OAAO,IAAI,OAAO;IAUlB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAIvD;;OAEG;IACH,uBAAuB,IAAI,MAAM;CAKlC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NostrIdentity - Links Nostr identity to Profile
|
|
3
|
+
*
|
|
4
|
+
* Stores the Nostr keypair with encrypted private key for custodial auth.
|
|
5
|
+
* The private key is encrypted using AES-256-GCM with the SERVER_MASTER_SECRET.
|
|
6
|
+
* The public key serves as the unique identifier for NIP-05 verification.
|
|
7
|
+
*/
|
|
8
|
+
import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
9
|
+
import type { Profile } from './Profile';
|
|
10
|
+
export interface NostrIdentityOptions extends SmrtObjectOptions {
|
|
11
|
+
profileId?: string;
|
|
12
|
+
pubkey?: string;
|
|
13
|
+
encryptedPrivkey?: string;
|
|
14
|
+
encryptionIv?: string;
|
|
15
|
+
encryptionTag?: string;
|
|
16
|
+
email?: string;
|
|
17
|
+
nip05Username?: string;
|
|
18
|
+
lastUsedAt?: Date | null;
|
|
19
|
+
verifiedAt?: Date | null;
|
|
20
|
+
}
|
|
21
|
+
export declare class NostrIdentity extends SmrtObject {
|
|
22
|
+
/**
|
|
23
|
+
* Link to the Profile (Person, Organization, Bot)
|
|
24
|
+
*/
|
|
25
|
+
profileId?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Hex-encoded secp256k1 public key (64 characters).
|
|
28
|
+
*
|
|
29
|
+
* Indexed: `findByPubkey()` looks identities up by this column (#2364,
|
|
30
|
+
* epic #2382 finding A3).
|
|
31
|
+
*/
|
|
32
|
+
pubkey: string;
|
|
33
|
+
/**
|
|
34
|
+
* AES-256-GCM encrypted private key (base64-encoded ciphertext)
|
|
35
|
+
*/
|
|
36
|
+
encryptedPrivkey: string;
|
|
37
|
+
/**
|
|
38
|
+
* Initialization vector for AES-GCM decryption (base64)
|
|
39
|
+
*/
|
|
40
|
+
encryptionIv: string;
|
|
41
|
+
/**
|
|
42
|
+
* Authentication tag from AES-GCM (base64)
|
|
43
|
+
*/
|
|
44
|
+
encryptionTag: string;
|
|
45
|
+
/**
|
|
46
|
+
* Email address associated with this identity
|
|
47
|
+
*/
|
|
48
|
+
email: string;
|
|
49
|
+
/**
|
|
50
|
+
* Username for NIP-05 verification (e.g., "alice" for alice@domain.com)
|
|
51
|
+
*/
|
|
52
|
+
nip05Username: string;
|
|
53
|
+
/**
|
|
54
|
+
* Last time this identity was used for authentication
|
|
55
|
+
*/
|
|
56
|
+
lastUsedAt: Date | null;
|
|
57
|
+
/**
|
|
58
|
+
* When this identity was verified via magic link
|
|
59
|
+
*/
|
|
60
|
+
verifiedAt: Date | null;
|
|
61
|
+
constructor(options?: NostrIdentityOptions);
|
|
62
|
+
/**
|
|
63
|
+
* Get the linked Profile
|
|
64
|
+
*/
|
|
65
|
+
getProfile(): Promise<Profile | null>;
|
|
66
|
+
/**
|
|
67
|
+
* Find identity by public key
|
|
68
|
+
*/
|
|
69
|
+
static findByPubkey(pubkey: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
|
|
70
|
+
/**
|
|
71
|
+
* Find identity by email
|
|
72
|
+
*/
|
|
73
|
+
static findByEmail(email: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
|
|
74
|
+
/**
|
|
75
|
+
* Find identity by NIP-05 username
|
|
76
|
+
*/
|
|
77
|
+
static findByNip05(username: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
|
|
78
|
+
/**
|
|
79
|
+
* Decrypt the private key using the server master secret
|
|
80
|
+
* @param masterSecret - SERVER_MASTER_SECRET from environment
|
|
81
|
+
* @returns Hex-encoded private key
|
|
82
|
+
*/
|
|
83
|
+
decryptPrivkey(masterSecret: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* Get the full keypair (requires master secret)
|
|
86
|
+
* @param masterSecret - SERVER_MASTER_SECRET from environment
|
|
87
|
+
*/
|
|
88
|
+
getKeypair(masterSecret: string): {
|
|
89
|
+
pubkey: string;
|
|
90
|
+
privkey: string;
|
|
91
|
+
npub: string;
|
|
92
|
+
nsec: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Record usage of this identity
|
|
96
|
+
*/
|
|
97
|
+
recordUsage(): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Mark this identity as verified
|
|
100
|
+
*/
|
|
101
|
+
markVerified(): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Check if this identity is verified
|
|
104
|
+
*/
|
|
105
|
+
isVerified(): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Get the NIP-05 identifier (username@domain)
|
|
108
|
+
* Note: Domain must be provided by the application
|
|
109
|
+
*/
|
|
110
|
+
getNip05Identifier(domain: string): string;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=NostrIdentity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NostrIdentity.d.ts","sourceRoot":"","sources":["../../src/models/NostrIdentity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B;AAED,qBASa,aAAc,SAAQ,UAAU;IAC3C;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;OAKG;IAEH,MAAM,EAAE,MAAM,CAAM;IAEpB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAM;IAE9B;;OAEG;IACH,YAAY,EAAE,MAAM,CAAM;IAE1B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAM;IAE3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;IAEnB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAM;IAE3B;;OAEG;IACH,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IACH,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;gBAEnB,OAAO,GAAE,oBAAyB;IAc9C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI3C;;OAEG;WACU,YAAY,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAUhC;;OAEG;WACU,WAAW,CACtB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAUhC;;OAEG;WACU,WAAW,CACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAUhC;;;;OAIG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAS5C;;;OAGG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG;QAChC,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd;IAUD;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBlC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAMnC;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;;OAGG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAI3C"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OidcIdentity - Links OIDC provider identities to Profile
|
|
3
|
+
*
|
|
4
|
+
* Stores the mapping between external OIDC providers (Keycloak, Google, GitHub)
|
|
5
|
+
* and internal Profile records. Multiple identities can link to a single profile.
|
|
6
|
+
*/
|
|
7
|
+
import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
8
|
+
import type { Profile } from './Profile';
|
|
9
|
+
export interface OidcIdentityOptions extends SmrtObjectOptions {
|
|
10
|
+
profileId?: string;
|
|
11
|
+
provider?: string;
|
|
12
|
+
issuer?: string;
|
|
13
|
+
subject?: string;
|
|
14
|
+
email?: string;
|
|
15
|
+
lastUsedAt?: Date | null;
|
|
16
|
+
}
|
|
17
|
+
export declare class OidcIdentity extends SmrtObject {
|
|
18
|
+
/**
|
|
19
|
+
* Link to the Profile (Person, Organization, Bot)
|
|
20
|
+
*/
|
|
21
|
+
profileId?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Provider name (e.g., 'keycloak', 'google', 'github')
|
|
24
|
+
*/
|
|
25
|
+
provider: string;
|
|
26
|
+
/**
|
|
27
|
+
* OIDC issuer URL (e.g., https://keycloak.example.com/realms/bmp)
|
|
28
|
+
*/
|
|
29
|
+
issuer: string;
|
|
30
|
+
/**
|
|
31
|
+
* OIDC subject claim - unique identifier from the provider
|
|
32
|
+
*/
|
|
33
|
+
subject: string;
|
|
34
|
+
/**
|
|
35
|
+
* Stable issuer+subject key used as the database race arbiter.
|
|
36
|
+
*
|
|
37
|
+
* Nullable for legacy rows; every newly linked or reused identity backfills
|
|
38
|
+
* it. A separate unique constraint makes concurrent first login fail with a
|
|
39
|
+
* retryable conflict instead of creating two identities.
|
|
40
|
+
*/
|
|
41
|
+
identityKey: string | null;
|
|
42
|
+
/**
|
|
43
|
+
* Cached email from the IdP (for display/lookup)
|
|
44
|
+
*/
|
|
45
|
+
email: string;
|
|
46
|
+
/**
|
|
47
|
+
* Last time this identity was used for authentication
|
|
48
|
+
*/
|
|
49
|
+
lastUsedAt: Date | null;
|
|
50
|
+
constructor(options?: OidcIdentityOptions);
|
|
51
|
+
/**
|
|
52
|
+
* Get the linked Profile
|
|
53
|
+
*/
|
|
54
|
+
getProfile(): Promise<Profile | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Find identity by issuer and subject
|
|
57
|
+
*/
|
|
58
|
+
static findBySubject(issuer: string, subject: string, options?: SmrtObjectOptions): Promise<OidcIdentity | null>;
|
|
59
|
+
/** Build the collision-free natural key for one OIDC issuer subject. */
|
|
60
|
+
static buildIdentityKey(issuer: string, subject: string): string;
|
|
61
|
+
/** Keep the durable key derived from its natural-key source fields. */
|
|
62
|
+
save(): Promise<this>;
|
|
63
|
+
/**
|
|
64
|
+
* Reuse an existing exact identity for its unchanged Profile.
|
|
65
|
+
*
|
|
66
|
+
* @deprecated Authentication links must be created through transactional
|
|
67
|
+
* provisioning. This compatibility method only refreshes a unique mapping
|
|
68
|
+
* that already belongs to the supplied Profile, including legacy Profile
|
|
69
|
+
* types, and deliberately refuses to create or rebind authority.
|
|
70
|
+
*/
|
|
71
|
+
static findOrCreate(profile: Profile, oidcData: {
|
|
72
|
+
provider: string;
|
|
73
|
+
issuer: string;
|
|
74
|
+
subject: string;
|
|
75
|
+
email?: string;
|
|
76
|
+
}, options?: SmrtObjectOptions): Promise<OidcIdentity>;
|
|
77
|
+
/**
|
|
78
|
+
* Record usage of this identity
|
|
79
|
+
*/
|
|
80
|
+
recordUsage(): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=OidcIdentity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OidcIdentity.d.ts","sourceRoot":"","sources":["../../src/models/OidcIdentity.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B;AAED,qBASa,YAAa,SAAQ,UAAU;IAC1C;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;OAEG;IAEH,MAAM,EAAE,MAAM,CAAM;IAEpB;;OAEG;IAEH,OAAO,EAAE,MAAM,CAAM;IAErB;;;;;;OAMG;IAEH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAElC;;OAEG;IAEH,KAAK,EAAE,MAAM,CAAM;IAEnB;;OAEG;IAEH,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;gBAEnB,OAAO,GAAE,mBAAwB;IAU7C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI3C;;OAEG;WACU,aAAa,CACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAQ/B,wEAAwE;IACxE,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAIhE,uEAAuE;IACxD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQpC;;;;;;;OAOG;WACU,YAAY,CACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,EACD,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,YAAY,CAAC;IA0BxB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAwBnC"}
|