@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
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* resolveIdentity - Resolves authentication context to a Profile
|
|
3
|
+
*
|
|
4
|
+
* Used by apps (blindmanpress.com) to resolve incoming auth to a Profile.
|
|
5
|
+
* Modules (aedile, praeco) should receive the resolved profile from the app.
|
|
6
|
+
*
|
|
7
|
+
* Resolution order:
|
|
8
|
+
* 1. API key header → ApiKey → Profile
|
|
9
|
+
* 2. OIDC session → OidcIdentity → Profile
|
|
10
|
+
* 3. Nostr auth → NostrIdentity → Profile
|
|
11
|
+
* 4. Actor header (CI pass-through) → Profile lookup
|
|
12
|
+
*/
|
|
13
|
+
import { type SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
14
|
+
import { ApiKey } from '../models/ApiKey';
|
|
15
|
+
import { NostrIdentity } from '../models/NostrIdentity';
|
|
16
|
+
import { OidcIdentity } from '../models/OidcIdentity';
|
|
17
|
+
import type { Profile } from '../models/Profile';
|
|
18
|
+
import { type NostrEvent } from './nostrCrypto';
|
|
19
|
+
/**
|
|
20
|
+
* Context provided to resolveIdentity
|
|
21
|
+
*/
|
|
22
|
+
export interface AuthContext {
|
|
23
|
+
/**
|
|
24
|
+
* API key from X-API-Key header or similar
|
|
25
|
+
*/
|
|
26
|
+
apiKey?: string | null;
|
|
27
|
+
/**
|
|
28
|
+
* OIDC session data (from @auth/sveltekit or similar)
|
|
29
|
+
*/
|
|
30
|
+
oidcSession?: {
|
|
31
|
+
sub?: string;
|
|
32
|
+
iss?: string;
|
|
33
|
+
email?: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
} | null;
|
|
36
|
+
/**
|
|
37
|
+
* Actor identifier for CI pass-through identity
|
|
38
|
+
* Usually the GitHub actor (username) who triggered the workflow
|
|
39
|
+
*/
|
|
40
|
+
actor?: string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Nostr authentication data (NIP-42 style)
|
|
43
|
+
*/
|
|
44
|
+
nostrAuth?: {
|
|
45
|
+
/** Signed Nostr event for authentication */
|
|
46
|
+
event: NostrEvent;
|
|
47
|
+
/** Expected challenge (to prevent replay attacks) */
|
|
48
|
+
challenge: string;
|
|
49
|
+
} | null;
|
|
50
|
+
/**
|
|
51
|
+
* Database/persistence options
|
|
52
|
+
*/
|
|
53
|
+
db?: SmrtObjectOptions['db'];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Result of identity resolution
|
|
57
|
+
*/
|
|
58
|
+
export interface ResolveIdentityResult {
|
|
59
|
+
/**
|
|
60
|
+
* The resolved profile, or null if not authenticated
|
|
61
|
+
*/
|
|
62
|
+
profile: Profile | null;
|
|
63
|
+
/**
|
|
64
|
+
* How the identity was resolved
|
|
65
|
+
*/
|
|
66
|
+
source: 'api_key' | 'oidc' | 'nostr' | 'actor' | 'none';
|
|
67
|
+
/**
|
|
68
|
+
* The API key record if authenticated via API key
|
|
69
|
+
*/
|
|
70
|
+
apiKey?: ApiKey;
|
|
71
|
+
/**
|
|
72
|
+
* The OIDC identity record if authenticated via OIDC
|
|
73
|
+
*/
|
|
74
|
+
oidcIdentity?: OidcIdentity;
|
|
75
|
+
/**
|
|
76
|
+
* The Nostr identity record if authenticated via Nostr
|
|
77
|
+
*/
|
|
78
|
+
nostrIdentity?: NostrIdentity;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Resolve authentication context to a Profile
|
|
82
|
+
*
|
|
83
|
+
* @param context - The authentication context from the request
|
|
84
|
+
* @returns The resolved profile and metadata
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* // In SvelteKit hooks.server.ts
|
|
89
|
+
* import { resolveIdentity } from '@happyvertical/smrt-profiles';
|
|
90
|
+
*
|
|
91
|
+
* const identityMiddleware: Handle = async ({ event, resolve }) => {
|
|
92
|
+
* const session = await event.locals.auth();
|
|
93
|
+
*
|
|
94
|
+
* const { profile, source } = await resolveIdentity({
|
|
95
|
+
* oidcSession: session,
|
|
96
|
+
* apiKey: event.request.headers.get('X-API-Key'),
|
|
97
|
+
* actor: event.request.headers.get('X-Actor'),
|
|
98
|
+
* db: { type: 'postgres', url: DATABASE_URL },
|
|
99
|
+
* });
|
|
100
|
+
*
|
|
101
|
+
* event.locals.profile = profile;
|
|
102
|
+
* event.locals.authSource = source;
|
|
103
|
+
*
|
|
104
|
+
* return resolve(event);
|
|
105
|
+
* };
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare function resolveIdentity(context: AuthContext): Promise<ResolveIdentityResult>;
|
|
109
|
+
/**
|
|
110
|
+
* Create a profile from OIDC claims if it doesn't exist
|
|
111
|
+
*
|
|
112
|
+
* Resolution order:
|
|
113
|
+
* 1. If OIDC identity (iss + sub) already exists → return linked profile
|
|
114
|
+
* 2. If the email matches an existing Profile, fail closed because this
|
|
115
|
+
* package cannot prove whether a User owns it
|
|
116
|
+
* 3. Otherwise, create new profile + identity
|
|
117
|
+
*
|
|
118
|
+
* Security considerations:
|
|
119
|
+
* - Existing issuer/subject links always keep their already-linked Profile,
|
|
120
|
+
* including legacy tenant-scoped or non-Person Profiles, and refresh the
|
|
121
|
+
* cached identity email. This exact-link compatibility does not perform
|
|
122
|
+
* email-based canonical reuse.
|
|
123
|
+
* - New identities never attach to an existing email match through this
|
|
124
|
+
* Profile-only helper because Profile ownership belongs to the users package.
|
|
125
|
+
* Use `UserCollection.getOrCreateFromOidc()` for owner-aware verified-email
|
|
126
|
+
* reuse and its supported pre-provision resolver hook.
|
|
127
|
+
* - This function trusts the OIDC provider to assert correct email_verified status.
|
|
128
|
+
* Only use with trusted providers.
|
|
129
|
+
*
|
|
130
|
+
* @param claims - OIDC token claims
|
|
131
|
+
* @param provider - Provider name (e.g., 'keycloak', 'google', 'github')
|
|
132
|
+
* @param options - Database options
|
|
133
|
+
* @returns The created or existing profile with linked OIDC identity
|
|
134
|
+
*/
|
|
135
|
+
export declare function createProfileFromOidc(claims: {
|
|
136
|
+
sub: string;
|
|
137
|
+
iss: string;
|
|
138
|
+
email?: string;
|
|
139
|
+
email_verified?: boolean;
|
|
140
|
+
name?: string;
|
|
141
|
+
preferred_username?: string;
|
|
142
|
+
}, provider: string, options: SmrtObjectOptions): Promise<{
|
|
143
|
+
profile: Profile;
|
|
144
|
+
oidcIdentity: OidcIdentity;
|
|
145
|
+
created: boolean;
|
|
146
|
+
}>;
|
|
147
|
+
/**
|
|
148
|
+
* @internal Transactionally reuse one exact legacy issuer/subject link.
|
|
149
|
+
*
|
|
150
|
+
* This path cannot create or rebind authority. It intentionally preserves
|
|
151
|
+
* existing tenant-scoped and non-Person Profile links; canonical global Person
|
|
152
|
+
* validation remains mandatory for every path that creates a User/session.
|
|
153
|
+
*/
|
|
154
|
+
export declare function reuseExistingOidcIdentityForProfile(profileId: string, claims: {
|
|
155
|
+
sub: string;
|
|
156
|
+
iss: string;
|
|
157
|
+
email?: string;
|
|
158
|
+
email_verified?: boolean;
|
|
159
|
+
name?: string;
|
|
160
|
+
preferred_username?: string;
|
|
161
|
+
}, provider: string, options: SmrtObjectOptions): Promise<{
|
|
162
|
+
profile: Profile;
|
|
163
|
+
oidcIdentity: OidcIdentity;
|
|
164
|
+
created: false;
|
|
165
|
+
}>;
|
|
166
|
+
/**
|
|
167
|
+
* Create a profile from Nostr identity (used by magic link service)
|
|
168
|
+
*
|
|
169
|
+
* This is typically called internally by the magic link service,
|
|
170
|
+
* but can be used directly if needed.
|
|
171
|
+
*
|
|
172
|
+
* @param email - Email address for the profile
|
|
173
|
+
* @param nostrData - Encrypted Nostr keypair data
|
|
174
|
+
* @param options - Database options
|
|
175
|
+
* @returns The created profile with linked Nostr identity
|
|
176
|
+
*/
|
|
177
|
+
export declare function createProfileFromNostr(email: string, nostrData: {
|
|
178
|
+
pubkey: string;
|
|
179
|
+
encryptedPrivkey: string;
|
|
180
|
+
encryptionIv: string;
|
|
181
|
+
encryptionTag: string;
|
|
182
|
+
nip05Username?: string;
|
|
183
|
+
}, options: SmrtObjectOptions): Promise<{
|
|
184
|
+
profile: Profile;
|
|
185
|
+
nostrIdentity: NostrIdentity;
|
|
186
|
+
created: boolean;
|
|
187
|
+
}>;
|
|
188
|
+
//# sourceMappingURL=resolveIdentity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveIdentity.d.ts","sourceRoot":"","sources":["../../src/auth/resolveIdentity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApiKeyCollection - Collection for managing API keys
|
|
3
|
+
*/
|
|
4
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
5
|
+
import { ApiKey, type GenerateKeyResult } from '../models/ApiKey';
|
|
6
|
+
import type { Profile } from '../models/Profile';
|
|
7
|
+
export declare class ApiKeyCollection extends SmrtCollection<ApiKey> {
|
|
8
|
+
static readonly _itemClass: typeof ApiKey;
|
|
9
|
+
/**
|
|
10
|
+
* Find all keys for a profile
|
|
11
|
+
*/
|
|
12
|
+
findByProfile(profileId: string): Promise<ApiKey[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Find active (non-revoked, non-expired) keys for a profile
|
|
15
|
+
*/
|
|
16
|
+
findActiveByProfile(profileId: string): Promise<ApiKey[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Find key by hash
|
|
19
|
+
*/
|
|
20
|
+
findByHash(keyHash: string): Promise<ApiKey | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Verify an API key string and return the record if valid
|
|
23
|
+
*/
|
|
24
|
+
verify(key: string): Promise<ApiKey | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Generate a new key for a profile
|
|
27
|
+
*/
|
|
28
|
+
generateForProfile(profile: Profile, options: {
|
|
29
|
+
name: string;
|
|
30
|
+
scopes?: string[];
|
|
31
|
+
expiresAt?: Date | null;
|
|
32
|
+
}): Promise<GenerateKeyResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Revoke all keys for a profile
|
|
35
|
+
*/
|
|
36
|
+
revokeAllForProfile(profileId: string): Promise<number>;
|
|
37
|
+
/**
|
|
38
|
+
* Revoke a specific key by prefix
|
|
39
|
+
*/
|
|
40
|
+
revokeByPrefix(keyPrefix: string): Promise<boolean>;
|
|
41
|
+
/**
|
|
42
|
+
* Clean up expired keys (soft delete by setting revokedAt)
|
|
43
|
+
*/
|
|
44
|
+
cleanupExpired(): Promise<number>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=ApiKeyCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiKeyCollection.d.ts","sourceRoot":"","sources":["../../src/collections/ApiKeyCollection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,qBAAa,gBAAiB,SAAQ,cAAc,CAAC,MAAM,CAAC;IAC1D,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAU;IAEpC;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAMzD;;OAEG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAK/D;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAMzD;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAiBjD;;OAEG;IACG,kBAAkB,CACtB,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;KACzB,GACA,OAAO,CAAC,iBAAiB,CAAC;IAO7B;;OAEG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ7D;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYzD;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;CAexC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuditLogCollection - Collection for querying audit logs
|
|
3
|
+
*/
|
|
4
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
5
|
+
import { AuditLog, type AuditSource } from '../models/AuditLog';
|
|
6
|
+
import type { Profile } from '../models/Profile';
|
|
7
|
+
export declare class AuditLogCollection extends SmrtCollection<AuditLog> {
|
|
8
|
+
static readonly _itemClass: typeof AuditLog;
|
|
9
|
+
/**
|
|
10
|
+
* Find logs for a profile (actions they performed)
|
|
11
|
+
*/
|
|
12
|
+
findByProfile(profileId: string): Promise<AuditLog[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Find logs for a resource
|
|
15
|
+
*/
|
|
16
|
+
findByResource(resourceType: string, resourceId: string): Promise<AuditLog[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Find logs by action type
|
|
19
|
+
*/
|
|
20
|
+
findByAction(action: string): Promise<AuditLog[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Find logs by source
|
|
23
|
+
*/
|
|
24
|
+
findBySource(source: AuditSource): Promise<AuditLog[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Find logs where actions were performed on behalf of someone
|
|
27
|
+
*/
|
|
28
|
+
findOnBehalfOf(profileId: string): Promise<AuditLog[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Record a new audit log entry
|
|
31
|
+
*/
|
|
32
|
+
record(options: {
|
|
33
|
+
profile: Profile;
|
|
34
|
+
action: string;
|
|
35
|
+
resourceType: string;
|
|
36
|
+
resourceId: string;
|
|
37
|
+
source?: AuditSource;
|
|
38
|
+
metadata?: Record<string, unknown>;
|
|
39
|
+
onBehalfOf?: Profile | null;
|
|
40
|
+
}): Promise<AuditLog>;
|
|
41
|
+
/**
|
|
42
|
+
* Get recent activity for a profile
|
|
43
|
+
*/
|
|
44
|
+
getRecentActivity(profileId: string, limit?: number): Promise<AuditLog[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Get activity timeline for a resource
|
|
47
|
+
*/
|
|
48
|
+
getResourceTimeline(resourceType: string, resourceId: string): Promise<AuditLog[]>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=AuditLogCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditLogCollection.d.ts","sourceRoot":"","sources":["../../src/collections/AuditLogCollection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,qBAAa,kBAAmB,SAAQ,cAAc,CAAC,QAAQ,CAAC;IAC9D,MAAM,CAAC,QAAQ,CAAC,UAAU,kBAAY;IAEtC;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO3D;;OAEG;IACG,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOtB;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOvD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO5D;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO5D;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;KAC7B,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgBrB;;OAEG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAQtB;;OAEG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;CAMvB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MagicLinkTokenCollection - Collection for managing magic link tokens
|
|
3
|
+
*/
|
|
4
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
5
|
+
import { MagicLinkToken } from '../models/MagicLinkToken';
|
|
6
|
+
export declare class MagicLinkTokenCollection extends SmrtCollection<MagicLinkToken> {
|
|
7
|
+
static readonly _itemClass: typeof MagicLinkToken;
|
|
8
|
+
/**
|
|
9
|
+
* Find token by hash
|
|
10
|
+
*/
|
|
11
|
+
findByTokenHash(tokenHash: string): Promise<MagicLinkToken | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Find active (non-expired, non-used) tokens for an email
|
|
14
|
+
*/
|
|
15
|
+
findActiveForEmail(email: string): Promise<MagicLinkToken[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Find tokens for a NostrIdentity
|
|
18
|
+
*/
|
|
19
|
+
findByIdentity(nostrIdentityId: string): Promise<MagicLinkToken[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Count tokens created for an email within a time window (for rate limiting)
|
|
22
|
+
* @param email - Email address
|
|
23
|
+
* @param withinMinutes - Time window in minutes
|
|
24
|
+
*/
|
|
25
|
+
countRecentByEmail(email: string, withinMinutes: number): Promise<number>;
|
|
26
|
+
/**
|
|
27
|
+
* Count tokens created from an IP within a time window (for rate limiting)
|
|
28
|
+
* @param ip - IP address
|
|
29
|
+
* @param withinMinutes - Time window in minutes
|
|
30
|
+
*/
|
|
31
|
+
countRecentByIp(ip: string, withinMinutes: number): Promise<number>;
|
|
32
|
+
/**
|
|
33
|
+
* Verify a token and return it if valid
|
|
34
|
+
*/
|
|
35
|
+
verify(token: string): Promise<MagicLinkToken | null>;
|
|
36
|
+
/**
|
|
37
|
+
* Clean up expired tokens by deleting them
|
|
38
|
+
* @returns Number of tokens deleted
|
|
39
|
+
*/
|
|
40
|
+
cleanupExpired(): Promise<number>;
|
|
41
|
+
/**
|
|
42
|
+
* Revoke all tokens for a NostrIdentity (e.g., when identity is deleted)
|
|
43
|
+
*/
|
|
44
|
+
revokeForIdentity(nostrIdentityId: string): Promise<number>;
|
|
45
|
+
/**
|
|
46
|
+
* Check if rate limit is exceeded for email
|
|
47
|
+
* @param email - Email address
|
|
48
|
+
* @param maxPerHour - Maximum tokens allowed per hour (default: 5)
|
|
49
|
+
*/
|
|
50
|
+
isRateLimitedByEmail(email: string, maxPerHour?: number): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Check if rate limit is exceeded for IP
|
|
53
|
+
* @param ip - IP address
|
|
54
|
+
* @param maxPerHour - Maximum tokens allowed per hour (default: 10)
|
|
55
|
+
*/
|
|
56
|
+
isRateLimitedByIp(ip: string, maxPerHour?: number): Promise<boolean>;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=MagicLinkTokenCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MagicLinkTokenCollection.d.ts","sourceRoot":"","sources":["../../src/collections/MagicLinkTokenCollection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,qBAAa,wBAAyB,SAAQ,cAAc,CAAC,cAAc,CAAC;IAC1E,MAAM,CAAC,QAAQ,CAAC,UAAU,wBAAkB;IAE5C;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAMxE;;OAEG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAOlE;;OAEG;IACG,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAMxE;;;;OAIG;IACG,kBAAkB,CACtB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC;IAclB;;;;OAIG;IACG,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAazE;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAe3D;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAevC;;OAEG;IACG,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcjE;;;;OAIG;IACG,oBAAoB,CACxB,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAU,GACrB,OAAO,CAAC,OAAO,CAAC;IAKnB;;;;OAIG;IACG,iBAAiB,CACrB,EAAE,EAAE,MAAM,EACV,UAAU,GAAE,MAAW,GACtB,OAAO,CAAC,OAAO,CAAC;CAIpB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NostrIdentityCollection - Collection for managing Nostr identity records
|
|
3
|
+
*/
|
|
4
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
5
|
+
import { NostrIdentity } from '../models/NostrIdentity';
|
|
6
|
+
import type { Profile } from '../models/Profile';
|
|
7
|
+
export interface Nip05Response {
|
|
8
|
+
names: Record<string, string>;
|
|
9
|
+
relays?: Record<string, string[]>;
|
|
10
|
+
}
|
|
11
|
+
export declare class NostrIdentityCollection extends SmrtCollection<NostrIdentity> {
|
|
12
|
+
static readonly _itemClass: typeof NostrIdentity;
|
|
13
|
+
/**
|
|
14
|
+
* Find identities for a profile
|
|
15
|
+
*/
|
|
16
|
+
findByProfile(profileId: string): Promise<NostrIdentity[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Find identity by public key
|
|
19
|
+
*/
|
|
20
|
+
findByPubkey(pubkey: string): Promise<NostrIdentity | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Find identity by email
|
|
23
|
+
*/
|
|
24
|
+
findByEmail(email: string): Promise<NostrIdentity | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Find identity by NIP-05 username
|
|
27
|
+
*/
|
|
28
|
+
findByNip05(username: string): Promise<NostrIdentity | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Link a new Nostr identity to a profile with a new keypair
|
|
31
|
+
* @param profile - The profile to link to
|
|
32
|
+
* @param email - Email address for this identity
|
|
33
|
+
* @param masterSecret - Server master secret for encryption
|
|
34
|
+
* @param nip05Username - Optional NIP-05 username (defaults to email local part)
|
|
35
|
+
*/
|
|
36
|
+
createForProfile(profile: Profile, email: string, masterSecret: string, nip05Username?: string): Promise<NostrIdentity>;
|
|
37
|
+
/**
|
|
38
|
+
* Link an existing Nostr identity (with encrypted keypair) to a profile
|
|
39
|
+
*/
|
|
40
|
+
linkToProfile(profile: Profile, nostrData: {
|
|
41
|
+
pubkey: string;
|
|
42
|
+
encryptedPrivkey: string;
|
|
43
|
+
encryptionIv: string;
|
|
44
|
+
encryptionTag: string;
|
|
45
|
+
email: string;
|
|
46
|
+
nip05Username?: string;
|
|
47
|
+
}): Promise<NostrIdentity>;
|
|
48
|
+
/**
|
|
49
|
+
* Unlink a Nostr identity from a profile
|
|
50
|
+
*/
|
|
51
|
+
unlinkFromProfile(profileId: string, pubkey: string): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Get NIP-05 response data for the /.well-known/nostr.json endpoint
|
|
54
|
+
* @param username - Optional username filter, returns all if not provided
|
|
55
|
+
*/
|
|
56
|
+
getNip05Response(username?: string): Promise<Nip05Response>;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a NIP-05 username is available
|
|
59
|
+
*/
|
|
60
|
+
isNip05Available(username: string): Promise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Update NIP-05 username for an identity
|
|
63
|
+
*/
|
|
64
|
+
updateNip05Username(identity: NostrIdentity, newUsername: string): Promise<NostrIdentity>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=NostrIdentityCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NostrIdentityCollection.d.ts","sourceRoot":"","sources":["../../src/collections/NostrIdentityCollection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACnC;AAED,qBAAa,uBAAwB,SAAQ,cAAc,CAAC,aAAa,CAAC;IACxE,MAAM,CAAC,QAAQ,CAAC,UAAU,uBAAiB;IAE3C;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAMhE;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAMjE;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAM/D;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAMlE;;;;;;OAMG;IACG,gBAAgB,CACpB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,aAAa,CAAC;IAqCzB;;OAEG;IACG,aAAa,CACjB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,gBAAgB,EAAE,MAAM,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GACA,OAAO,CAAC,aAAa,CAAC;IAgCzB;;OAEG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAY5E;;;OAGG;IACG,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAoBjE;;OAEG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1D;;OAEG;IACG,mBAAmB,CACvB,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,CAAC;CAc1B"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OidcIdentityCollection - Collection for managing OIDC identity records
|
|
3
|
+
*/
|
|
4
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
5
|
+
import { OidcIdentity } from '../models/OidcIdentity';
|
|
6
|
+
import type { Profile } from '../models/Profile';
|
|
7
|
+
/** More than one legacy row maps the same opaque OIDC issuer and subject. */
|
|
8
|
+
export declare class AmbiguousOidcIdentityError extends Error {
|
|
9
|
+
readonly issuer: string;
|
|
10
|
+
readonly subject: string;
|
|
11
|
+
constructor(issuer: string, subject: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class OidcIdentityCollection extends SmrtCollection<OidcIdentity> {
|
|
14
|
+
static readonly _itemClass: typeof OidcIdentity;
|
|
15
|
+
/**
|
|
16
|
+
* Find identities for a profile
|
|
17
|
+
*/
|
|
18
|
+
findByProfile(profileId: string): Promise<OidcIdentity[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Find identity by issuer and subject
|
|
21
|
+
*/
|
|
22
|
+
findBySubject(issuer: string, subject: string): Promise<OidcIdentity | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Find identities by provider
|
|
25
|
+
*/
|
|
26
|
+
findByProvider(provider: string): Promise<OidcIdentity[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Reuse an existing exact OIDC identity for its unchanged Profile.
|
|
29
|
+
*
|
|
30
|
+
* @deprecated New authentication links require the owner-aware,
|
|
31
|
+
* transactional provisioning APIs. This compatibility helper may refresh a
|
|
32
|
+
* legacy Profile type, but refuses to create or rebind authority.
|
|
33
|
+
*/
|
|
34
|
+
linkToProfile(profile: Profile, oidcData: {
|
|
35
|
+
provider: string;
|
|
36
|
+
issuer: string;
|
|
37
|
+
subject: string;
|
|
38
|
+
email?: string;
|
|
39
|
+
}): Promise<OidcIdentity>;
|
|
40
|
+
/**
|
|
41
|
+
* Unlink an OIDC identity from a profile
|
|
42
|
+
*/
|
|
43
|
+
unlinkFromProfile(profileId: string, issuer: string, subject: string): Promise<boolean>;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=OidcIdentityCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OidcIdentityCollection.d.ts","sourceRoot":"","sources":["../../src/collections/OidcIdentityCollection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,6EAA6E;AAC7E,qBAAa,0BAA2B,SAAQ,KAAK;IAEjD,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM;gBADf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;CAK3B;AAED,qBAAa,sBAAuB,SAAQ,cAAc,CAAC,YAAY,CAAC;IACtE,MAAM,CAAC,QAAQ,CAAC,UAAU,sBAAgB;IAE1C;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAM/D;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA0B/B;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAM/D;;;;;;OAMG;IACG,aAAa,CACjB,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,GACA,OAAO,CAAC,YAAY,CAAC;IAIxB;;OAEG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC;CAWpB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
2
|
+
import { OidcProfileEmailReservation } from '../models/OidcProfileEmailReservation';
|
|
3
|
+
/** Internal collection for canonical OIDC email reservations. */
|
|
4
|
+
export declare class OidcProfileEmailReservationCollection extends SmrtCollection<OidcProfileEmailReservation> {
|
|
5
|
+
static readonly _itemClass: typeof OidcProfileEmailReservation;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=OidcProfileEmailReservationCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OidcProfileEmailReservationCollection.d.ts","sourceRoot":"","sources":["../../src/collections/OidcProfileEmailReservationCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAEpF,iEAAiE;AACjE,qBAAa,qCAAsC,SAAQ,cAAc,CAAC,2BAA2B,CAAC;IACpG,MAAM,CAAC,QAAQ,CAAC,UAAU,qCAA+B;CAC1D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Asset } from '@happyvertical/smrt-assets';
|
|
2
|
+
import type { SmrtCollectionOptions } from '@happyvertical/smrt-core';
|
|
3
|
+
import { SmrtJunction } from '@happyvertical/smrt-core';
|
|
4
|
+
import { ProfileAsset } from '../models/ProfileAsset';
|
|
5
|
+
export interface ProfileAssetCollectionOptions extends SmrtCollectionOptions {
|
|
6
|
+
}
|
|
7
|
+
export declare class ProfileAssetCollection extends SmrtJunction<ProfileAsset> {
|
|
8
|
+
static readonly _itemClass: typeof ProfileAsset;
|
|
9
|
+
protected leftField: string;
|
|
10
|
+
protected rightField: string;
|
|
11
|
+
private profileCollectionPromise;
|
|
12
|
+
private getProfileCollection;
|
|
13
|
+
getAssets(profileId: string, relationship?: string): Promise<Asset[]>;
|
|
14
|
+
addAsset(profileId: string, asset: Asset, relationship?: string, sortOrder?: number): Promise<void>;
|
|
15
|
+
removeAsset(profileId: string, assetId: string, relationship?: string): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=ProfileAssetCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfileAssetCollection.d.ts","sourceRoot":"","sources":["../../src/collections/ProfileAssetCollection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAMxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAQ,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtD,MAAM,WAAW,6BAA8B,SAAQ,qBAAqB;CAAG;AAE/E,qBAKa,sBAAuB,SAAQ,YAAY,CAAC,YAAY,CAAC;IACpE,MAAM,CAAC,QAAQ,CAAC,UAAU,sBAAgB;IAC1C,SAAS,CAAC,SAAS,SAAe;IAClC,SAAS,CAAC,UAAU,SAAa;IAEjC,OAAO,CAAC,wBAAwB,CAA2C;YAE7D,oBAAoB;IAS5B,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAQrE,QAAQ,CACZ,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,KAAK,EACZ,YAAY,SAAe,EAC3B,SAAS,SAAI,GACZ,OAAO,CAAC,IAAI,CAAC;IAWV,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;CASjB"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProfileCollection - Collection manager for Profile objects
|
|
3
|
+
*
|
|
4
|
+
* Provides advanced querying and batch operations for Profile entities.
|
|
5
|
+
*/
|
|
6
|
+
import type { Asset } from '@happyvertical/smrt-assets';
|
|
7
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
8
|
+
import { Profile } from '../models/Profile';
|
|
9
|
+
export type CanonicalPersonProfileErrorCode = 'ambiguous_email' | 'email_key_backfill_required' | 'email_mismatch' | 'missing_profile' | 'non_person' | 'reservation_conflict' | 'tenant_scoped';
|
|
10
|
+
/** A Profile cannot safely represent one global human identity. */
|
|
11
|
+
export declare class CanonicalPersonProfileError extends Error {
|
|
12
|
+
readonly code: CanonicalPersonProfileErrorCode;
|
|
13
|
+
constructor(code: CanonicalPersonProfileErrorCode, message: string);
|
|
14
|
+
}
|
|
15
|
+
export declare class ProfileCollection extends SmrtCollection<Profile> {
|
|
16
|
+
static readonly _itemClass: typeof Profile;
|
|
17
|
+
private emailKeysReadyPromise;
|
|
18
|
+
/**
|
|
19
|
+
* Find a profile by email address
|
|
20
|
+
*
|
|
21
|
+
* @param email - The email address to search for
|
|
22
|
+
* @returns The matching profile or null
|
|
23
|
+
*/
|
|
24
|
+
findByEmail(email: string): Promise<Profile | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve one unambiguous global Person by normalized email.
|
|
27
|
+
*
|
|
28
|
+
* Unlike `findByEmail()`, this identity-boundary helper deliberately reads
|
|
29
|
+
* across tenant scopes and fails closed when any matching row is
|
|
30
|
+
* tenant-scoped, is not a Person STI row, or when more than one row matches
|
|
31
|
+
* case-insensitively. It is intended for verified external identities.
|
|
32
|
+
*/
|
|
33
|
+
findUniqueGlobalPersonByEmail(email: string): Promise<Profile | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Validate and hydrate a supplied canonical Profile.
|
|
36
|
+
*
|
|
37
|
+
* The Profile must be the sole case-insensitive match for its stored email.
|
|
38
|
+
* When `email` is provided, that address must also match the stored email.
|
|
39
|
+
*/
|
|
40
|
+
requireCanonicalGlobalPerson(profileId: string, email?: string): Promise<Profile>;
|
|
41
|
+
/**
|
|
42
|
+
* Reserve the normalized email for a previously validated canonical Person.
|
|
43
|
+
*
|
|
44
|
+
* The unique stored key turns a concurrent OIDC first-login race into a
|
|
45
|
+
* retryable database conflict. Legacy Profiles remain unaffected until an
|
|
46
|
+
* identity boundary safely claims them.
|
|
47
|
+
*/
|
|
48
|
+
reserveCanonicalIdentityEmail(profileId: string, email?: string): Promise<Profile>;
|
|
49
|
+
/**
|
|
50
|
+
* Find profiles by type slug
|
|
51
|
+
*
|
|
52
|
+
* @param typeSlug - The profile type slug to filter by
|
|
53
|
+
* @returns Array of matching profiles
|
|
54
|
+
*/
|
|
55
|
+
findByType(typeSlug: string): Promise<Profile[]>;
|
|
56
|
+
private requireDatabase;
|
|
57
|
+
private loadCanonicalEmailRows;
|
|
58
|
+
/** Require the deploy-time backfill marker before indexed identity reads. */
|
|
59
|
+
private ensureEmailKeysReady;
|
|
60
|
+
private checkEmailKeysReady;
|
|
61
|
+
private isStaleEmailReservation;
|
|
62
|
+
private assertRowEmailKeyCurrent;
|
|
63
|
+
private assertCanonicalRows;
|
|
64
|
+
private requireHydratedProfile;
|
|
65
|
+
/**
|
|
66
|
+
* Batch get metadata for multiple profiles
|
|
67
|
+
*
|
|
68
|
+
* @param profileIds - Array of profile UUIDs
|
|
69
|
+
* @returns Map of profile ID to metadata object
|
|
70
|
+
*/
|
|
71
|
+
batchGetMetadata(profileIds: string[]): Promise<Map<string, Record<string, string>>>;
|
|
72
|
+
/**
|
|
73
|
+
* Batch update metadata for multiple profiles
|
|
74
|
+
*
|
|
75
|
+
* @param updates - Array of { profileId, data } objects
|
|
76
|
+
*/
|
|
77
|
+
batchUpdateMetadata(updates: Array<{
|
|
78
|
+
profileId: string;
|
|
79
|
+
data: Record<string, unknown>;
|
|
80
|
+
}>): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Find related profiles for a given profile
|
|
83
|
+
*
|
|
84
|
+
* @param profileId - The profile UUID
|
|
85
|
+
* @param relationshipSlug - Optional filter by relationship type
|
|
86
|
+
* @returns Array of related profiles
|
|
87
|
+
*/
|
|
88
|
+
findRelated(profileId: string, relationshipSlug?: string): Promise<Profile[]>;
|
|
89
|
+
getAssets(profileId: string, relationship?: string): Promise<Asset[]>;
|
|
90
|
+
addAsset(profileId: string, asset: Asset, relationship?: string, sortOrder?: number): Promise<void>;
|
|
91
|
+
removeAsset(profileId: string, assetId: string, relationship?: string): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Get the relationship network for a profile up to a maximum depth
|
|
94
|
+
*
|
|
95
|
+
* @param profileId - The starting profile UUID
|
|
96
|
+
* @param options - Configuration options
|
|
97
|
+
* @returns Map of profile ID to depth level
|
|
98
|
+
*/
|
|
99
|
+
getRelationshipNetwork(profileId: string, options?: {
|
|
100
|
+
maxDepth?: number;
|
|
101
|
+
}): Promise<Map<string, number>>;
|
|
102
|
+
/**
|
|
103
|
+
* Find all profiles belonging to a specific tenant
|
|
104
|
+
*
|
|
105
|
+
* @param tenantId - The tenant UUID to filter by
|
|
106
|
+
* @returns Array of profiles for this tenant
|
|
107
|
+
*/
|
|
108
|
+
findByTenant(tenantId: string): Promise<Profile[]>;
|
|
109
|
+
/**
|
|
110
|
+
* Find all global profiles (no tenant association).
|
|
111
|
+
*
|
|
112
|
+
* Routes through the shared tenant-global helper so it does not throw under
|
|
113
|
+
* an active tenant context (an explicit `tenant_id IS NULL` filter would be
|
|
114
|
+
* flagged as an isolation violation). (#1600)
|
|
115
|
+
*
|
|
116
|
+
* @returns Array of profiles with null tenantId
|
|
117
|
+
*/
|
|
118
|
+
findGlobal(): Promise<Profile[]>;
|
|
119
|
+
/**
|
|
120
|
+
* Find profiles belonging to a tenant plus all global profiles.
|
|
121
|
+
*
|
|
122
|
+
* Fails closed if an active tenant context requests a different tenant's
|
|
123
|
+
* rows; the admin/system path keeps the cross-tenant capability. (#1600)
|
|
124
|
+
*
|
|
125
|
+
* @param tenantId - The tenant UUID to include
|
|
126
|
+
* @returns Array of tenant-specific and global profiles
|
|
127
|
+
*/
|
|
128
|
+
findWithGlobals(tenantId: string): Promise<Profile[]>;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=ProfileCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfileCollection.d.ts","sourceRoot":"","sources":["../../src/collections/ProfileCollection.ts"],"names":[],"mappings":"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"}
|