@happyvertical/smrt-users 0.57.2 → 0.57.3
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/README.md +58 -0
- package/dist/chunks/{TerminalAuthService-DUJYJWPP.js → TerminalAuthService-BBWemruU.js} +3 -3
- package/dist/chunks/TerminalAuthService-BBWemruU.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +610 -6
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +2176 -1
- package/dist/member-register/index.d.ts +3 -0
- package/dist/member-register/index.d.ts.map +1 -0
- package/dist/member-register/models.d.ts +103 -0
- package/dist/member-register/models.d.ts.map +1 -0
- package/dist/member-register/service.d.ts +79 -0
- package/dist/member-register/service.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +688 -7
- package/dist/sveltekit.js +1 -1
- package/package.json +10 -10
- package/dist/chunks/TerminalAuthService-DUJYJWPP.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,13 +1,617 @@
|
|
|
1
|
-
import { $ as PermissionResolver, $t as GroupCollection, A as withSessionPermissionContext, At as recordTenantHierarchyChanges, B as resolveOidcProviderConfig, Bt as RoleCollection, C as OperationPermissionError, Ct as TenantCollection, D as getCurrentSessionPermissionContext, Dt as applyTenantHierarchyUpdates, E as hasOperationPermission, Et as TenantHierarchyError, F as OidcLoginError, Ft as deriveOperationPermissionSlug, G as DeviceCredentialForbiddenError, Gt as UsersPasswordCredential, H as DEFAULT_DEVICE_PERSON_IDLE_SECONDS, Ht as UsersPinCredential, I as OidcLoginService, It as normalizeOperationPermissionAction, J as PIN_LOGIN_KIND, Jt as MembershipCollection, K as DeviceCredentialPolicyError, Kt as MembershipOverrideCollection, L as decodeOidcTransaction, Lt as registerPermissionDefinitions, M as MobileAuthService, Mt as RolePermissionCollection, N as readMobileBearerToken, Nt as PermissionCatalogService, O as getRequestScopedDatabase, Ot as assertTenantTableName, P as validateMobileRedirectUri, Pt as deriveOperationPermissionCollectionName, Q as SessionService, Qt as GroupMember, R as encodeOidcTransaction, Rt as syncPermissionCatalog, S as outOfBandProofSessionData, St as TenantPermissionOverride, T as checkOperationPermission, Tt as MAX_TENANT_HIERARCHY_DEPTH, U as DEFAULT_PIN_MANAGE_PERMISSION, Ut as PermissionCollection, Vt as UsersPinCredentialCollection, W as DeviceCredentialError, Wt as UsersPasswordCredentialCollection, X as PinVerifier, Xt as GroupRole, Y as PIN_PERMISSION_DEFINITIONS, Yt as GroupRoleCollection, Z as ensurePinPermissionsRegistered, Zt as GroupMemberCollection, _ as PasswordCredentialError, _n as Membership, _t as UserCollection, a as TerminalAuthError, an as UsersCliAuthRequestCollection, at as DEFAULT_SOURCE_LOCKOUT_AUDIT_SECONDS, b as PasswordPolicyError, bt as backfillUserEmailKeys, c as DEFAULT_PASSWORD_DENYLIST, cn as User, ct as LoginAttemptLimiter, d as DEFAULT_PASSWORD_MIN_LENGTH, dn as DEFAULT_SESSION_TTL, dt as ANCESTOR_READ_ACTION, en as Group, et as DEFAULT_LOGIN_ATTEMPT_WINDOW_SECONDS, f as DEFAULT_PASSWORD_RECOVERY_MAX_AGE_SECONDS, fn as SESSION_DATA_KEYS, ft as DEFAULT_ANCESTOR_READ_MAX_DEPTH, g as PASSWORD_RECOVERY_MAX_AGE_CEILING_SECONDS, gn as Permission, gt as OidcProvisioningError, h as PASSWORD_PERMISSION_DEFINITIONS, hn as Role, ht as normalizeAncestorReadPolicy, i as TERMINAL_APPROVE_LOGIN_KIND, in as UsersLoginAttempt, it as DEFAULT_LOGIN_MAX_ATTEMPTS, j as MobileAuthError, jt as DEFAULT_ROLE_PERMISSION_PATTERNS, k as withPrincipalPermissionContext, kt as planTenantHierarchy, l as DEFAULT_PASSWORD_MANAGE_PERMISSION, ln as isValidEmail, lt as LoginRateLimitError, m as PASSWORD_MAX_LENGTH_CEILING, mn as generateSessionId, mt as isAncestorReadableSlug, n as DEFAULT_CLI_AUTH_REQUEST_TTL_SECONDS, nn as UsersLoginAuditEvent, nt as DEFAULT_LOGIN_LOCKOUT_FACTOR, o as TerminalAuthRateLimitError, on as SessionCollection, ot as DurableLoginAuditSink, p as PASSWORD_LOGIN_KIND, pn as Session, pt as getConfiguredAncestorReadPolicy, q as DeviceCredentialService, qt as MembershipOverride, r as DEFAULT_CLI_SESSION_TTL_SECONDS, rn as UsersLoginAttemptCollection, rt as DEFAULT_LOGIN_LOCKOUT_MAX_SECONDS, s as TerminalAuthService, sn as UsersCliAuthRequest, st as InvalidCredentialsError, t as DEFAULT_CLI_AUTH_POLL_INTERVAL_SECONDS, tn as UsersLoginAuditEventCollection, tt as DEFAULT_LOGIN_LOCKOUT_BASE_SECONDS, u as DEFAULT_PASSWORD_MAX_LENGTH, un as normalizeEmail, ut as withoutListBounds, v as PasswordCredentialForbiddenError, w as assertOperationPermission, wt as Tenant, x as ensurePasswordPermissionsRegistered, xt as TenantPermissionOverrideCollection, y as PasswordCredentialService, yt as UserEmailKeyBackfillError, z as getUsersOidcConfig, zt as RolePermission } from "./chunks/TerminalAuthService-
|
|
1
|
+
import { $ as PermissionResolver, $t as GroupCollection, A as withSessionPermissionContext, At as recordTenantHierarchyChanges, B as resolveOidcProviderConfig, Bt as RoleCollection, C as OperationPermissionError, Ct as TenantCollection, D as getCurrentSessionPermissionContext, Dt as applyTenantHierarchyUpdates, E as hasOperationPermission, Et as TenantHierarchyError, F as OidcLoginError, Ft as deriveOperationPermissionSlug, G as DeviceCredentialForbiddenError, Gt as UsersPasswordCredential, H as DEFAULT_DEVICE_PERSON_IDLE_SECONDS, Ht as UsersPinCredential, I as OidcLoginService, It as normalizeOperationPermissionAction, J as PIN_LOGIN_KIND, Jt as MembershipCollection, K as DeviceCredentialPolicyError, Kt as MembershipOverrideCollection, L as decodeOidcTransaction, Lt as registerPermissionDefinitions, M as MobileAuthService, Mt as RolePermissionCollection, N as readMobileBearerToken, Nt as PermissionCatalogService, O as getRequestScopedDatabase, Ot as assertTenantTableName, P as validateMobileRedirectUri, Pt as deriveOperationPermissionCollectionName, Q as SessionService, Qt as GroupMember, R as encodeOidcTransaction, Rt as syncPermissionCatalog, S as outOfBandProofSessionData, St as TenantPermissionOverride, T as checkOperationPermission, Tt as MAX_TENANT_HIERARCHY_DEPTH, U as DEFAULT_PIN_MANAGE_PERMISSION, Ut as PermissionCollection, Vt as UsersPinCredentialCollection, W as DeviceCredentialError, Wt as UsersPasswordCredentialCollection, X as PinVerifier, Xt as GroupRole, Y as PIN_PERMISSION_DEFINITIONS, Yt as GroupRoleCollection, Z as ensurePinPermissionsRegistered, Zt as GroupMemberCollection, _ as PasswordCredentialError, _n as Membership, _t as UserCollection, a as TerminalAuthError, an as UsersCliAuthRequestCollection, at as DEFAULT_SOURCE_LOCKOUT_AUDIT_SECONDS, b as PasswordPolicyError, bt as backfillUserEmailKeys, c as DEFAULT_PASSWORD_DENYLIST, cn as User, ct as LoginAttemptLimiter, d as DEFAULT_PASSWORD_MIN_LENGTH, dn as DEFAULT_SESSION_TTL, dt as ANCESTOR_READ_ACTION, en as Group, et as DEFAULT_LOGIN_ATTEMPT_WINDOW_SECONDS, f as DEFAULT_PASSWORD_RECOVERY_MAX_AGE_SECONDS, fn as SESSION_DATA_KEYS, ft as DEFAULT_ANCESTOR_READ_MAX_DEPTH, g as PASSWORD_RECOVERY_MAX_AGE_CEILING_SECONDS, gn as Permission, gt as OidcProvisioningError, h as PASSWORD_PERMISSION_DEFINITIONS, hn as Role, ht as normalizeAncestorReadPolicy, i as TERMINAL_APPROVE_LOGIN_KIND, in as UsersLoginAttempt, it as DEFAULT_LOGIN_MAX_ATTEMPTS, j as MobileAuthError, jt as DEFAULT_ROLE_PERMISSION_PATTERNS, k as withPrincipalPermissionContext, kt as planTenantHierarchy, l as DEFAULT_PASSWORD_MANAGE_PERMISSION, ln as isValidEmail, lt as LoginRateLimitError, m as PASSWORD_MAX_LENGTH_CEILING, mn as generateSessionId, mt as isAncestorReadableSlug, n as DEFAULT_CLI_AUTH_REQUEST_TTL_SECONDS, nn as UsersLoginAuditEvent, nt as DEFAULT_LOGIN_LOCKOUT_FACTOR, o as TerminalAuthRateLimitError, on as SessionCollection, ot as DurableLoginAuditSink, p as PASSWORD_LOGIN_KIND, pn as Session, pt as getConfiguredAncestorReadPolicy, q as DeviceCredentialService, qt as MembershipOverride, r as DEFAULT_CLI_SESSION_TTL_SECONDS, rn as UsersLoginAttemptCollection, rt as DEFAULT_LOGIN_LOCKOUT_MAX_SECONDS, s as TerminalAuthService, sn as UsersCliAuthRequest, st as InvalidCredentialsError, t as DEFAULT_CLI_AUTH_POLL_INTERVAL_SECONDS, tn as UsersLoginAuditEventCollection, tt as DEFAULT_LOGIN_LOCKOUT_BASE_SECONDS, u as DEFAULT_PASSWORD_MAX_LENGTH, un as normalizeEmail, ut as withoutListBounds, v as PasswordCredentialForbiddenError, w as assertOperationPermission, wt as Tenant, x as ensurePasswordPermissionsRegistered, xt as TenantPermissionOverrideCollection, y as PasswordCredentialService, yt as UserEmailKeyBackfillError, z as getUsersOidcConfig, zt as RolePermission } from "./chunks/TerminalAuthService-BBWemruU.js";
|
|
2
2
|
import { a as MembershipStatus, c as TenantPermissionEffect, i as DEFAULT_TENANT_POLICY, l as TenantStatus, n as DEFAULT_ROLES, o as OverrideEffect, r as DEFAULT_ROLE_SLUGS, s as SessionStatus, t as AccessRequestStatus, u as UserStatus } from "./chunks/types-DFqeph0R.js";
|
|
3
|
-
import { ObjectRegistry, SmrtCollection, SmrtObject, SmrtRecipe, bumpChangeFeed, ensureChangeFeedTable, field, findManifestEntryByQualifiedName, foreignKey, isEmbeddedDatabase, isUniqueViolationError, registerRetentionTask, smrt, unregisterRetentionTask, withEmbeddedWriteTransaction } from "@happyvertical/smrt-core";
|
|
3
|
+
import { ObjectRegistry, SmrtCollection, SmrtObject, SmrtRecipe, bumpChangeFeed, crossPackageRef, ensureChangeFeedTable, field, findManifestEntryByQualifiedName, foreignKey, isEmbeddedDatabase, isUniqueViolationError, registerRetentionTask, smrt, unregisterRetentionTask, withEmbeddedWriteTransaction } from "@happyvertical/smrt-core";
|
|
4
|
+
import { TenantScoped, getTenantId, tenantId, withSystemContext, withTenant, withTenantGlobalRead } from "@happyvertical/smrt-tenancy";
|
|
4
5
|
import { PROFILE_EMAIL_KEY_BACKFILL_NAME, Person, ProfileCollection, ProfileTypeCollection, normalizeIdentityEmail } from "@happyvertical/smrt-profiles";
|
|
5
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
6
7
|
import { setTimeout } from "node:timers/promises";
|
|
7
|
-
import { TenantScoped, tenantId, withSystemContext } from "@happyvertical/smrt-tenancy";
|
|
8
8
|
import { createLogger } from "@happyvertical/logger";
|
|
9
9
|
import { BackfillTracker } from "@happyvertical/smrt-core/migrations";
|
|
10
10
|
import { OAuthServerError } from "@happyvertical/auth/server";
|
|
11
|
+
//#region src/member-register/models.ts
|
|
12
|
+
var __defProp$6 = Object.defineProperty;
|
|
13
|
+
var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
|
|
14
|
+
var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value
|
|
19
|
+
}) : obj[key] = value;
|
|
20
|
+
var __decorateClass$6 = (decorators, target, key, kind) => {
|
|
21
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
|
|
22
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
23
|
+
if (kind && result) __defProp$6(target, key, result);
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
27
|
+
var MemberClass = class extends SmrtObject {
|
|
28
|
+
tenantId = "";
|
|
29
|
+
key = "";
|
|
30
|
+
name = "";
|
|
31
|
+
description = "";
|
|
32
|
+
policyMetadata = null;
|
|
33
|
+
};
|
|
34
|
+
__publicField$6(MemberClass, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
35
|
+
__decorateClass$6([tenantId()], MemberClass.prototype, "tenantId", 2);
|
|
36
|
+
__decorateClass$6([field({ type: "text" })], MemberClass.prototype, "key", 2);
|
|
37
|
+
__decorateClass$6([field({
|
|
38
|
+
type: "json",
|
|
39
|
+
nullable: true
|
|
40
|
+
})], MemberClass.prototype, "policyMetadata", 2);
|
|
41
|
+
MemberClass = __decorateClass$6([TenantScoped({ mode: "required" }), smrt({
|
|
42
|
+
tableName: "member_classes",
|
|
43
|
+
sensitive: true,
|
|
44
|
+
indexes: [{
|
|
45
|
+
name: "member_classes_tenant_key_uq",
|
|
46
|
+
columns: ["tenantId", "key"],
|
|
47
|
+
unique: true
|
|
48
|
+
}],
|
|
49
|
+
api: { include: [] },
|
|
50
|
+
mcp: { include: [] },
|
|
51
|
+
cli: false
|
|
52
|
+
})], MemberClass);
|
|
53
|
+
var LegalMember = class extends SmrtObject {
|
|
54
|
+
tenantId = "";
|
|
55
|
+
memberClassId = "";
|
|
56
|
+
kind = "individual";
|
|
57
|
+
displayName = "";
|
|
58
|
+
userId = null;
|
|
59
|
+
profileId = null;
|
|
60
|
+
externalPartyRef = null;
|
|
61
|
+
joinedOn = "";
|
|
62
|
+
leftOn = null;
|
|
63
|
+
status = "active";
|
|
64
|
+
};
|
|
65
|
+
__publicField$6(LegalMember, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
66
|
+
__decorateClass$6([tenantId()], LegalMember.prototype, "tenantId", 2);
|
|
67
|
+
__decorateClass$6([foreignKey("MemberClass", { onDelete: "RESTRICT" })], LegalMember.prototype, "memberClassId", 2);
|
|
68
|
+
__decorateClass$6([field({ type: "text" })], LegalMember.prototype, "kind", 2);
|
|
69
|
+
__decorateClass$6([foreignKey("User", {
|
|
70
|
+
nullable: true,
|
|
71
|
+
onDelete: "RESTRICT"
|
|
72
|
+
})], LegalMember.prototype, "userId", 2);
|
|
73
|
+
__decorateClass$6([crossPackageRef("@happyvertical/smrt-profiles:Profile", {
|
|
74
|
+
nullable: true,
|
|
75
|
+
onDelete: "RESTRICT"
|
|
76
|
+
})], LegalMember.prototype, "profileId", 2);
|
|
77
|
+
__decorateClass$6([field({
|
|
78
|
+
type: "text",
|
|
79
|
+
nullable: true
|
|
80
|
+
})], LegalMember.prototype, "externalPartyRef", 2);
|
|
81
|
+
__decorateClass$6([field({ type: "text" })], LegalMember.prototype, "joinedOn", 2);
|
|
82
|
+
__decorateClass$6([field({
|
|
83
|
+
type: "text",
|
|
84
|
+
nullable: true
|
|
85
|
+
})], LegalMember.prototype, "leftOn", 2);
|
|
86
|
+
__decorateClass$6([field({ type: "text" })], LegalMember.prototype, "status", 2);
|
|
87
|
+
LegalMember = __decorateClass$6([TenantScoped({ mode: "required" }), smrt({
|
|
88
|
+
tableName: "legal_members",
|
|
89
|
+
sensitive: true,
|
|
90
|
+
indexes: [{
|
|
91
|
+
name: "legal_members_tenant_class_status_idx",
|
|
92
|
+
columns: [
|
|
93
|
+
"tenantId",
|
|
94
|
+
"memberClassId",
|
|
95
|
+
"status"
|
|
96
|
+
]
|
|
97
|
+
}, {
|
|
98
|
+
name: "legal_members_tenant_user_idx",
|
|
99
|
+
columns: ["tenantId", "userId"]
|
|
100
|
+
}],
|
|
101
|
+
api: { include: [] },
|
|
102
|
+
mcp: { include: [] },
|
|
103
|
+
cli: false
|
|
104
|
+
})], LegalMember);
|
|
105
|
+
var LegalMemberStatusHistory = class extends SmrtObject {
|
|
106
|
+
tenantId = "";
|
|
107
|
+
memberId = "";
|
|
108
|
+
status = "active";
|
|
109
|
+
effectiveOn = "";
|
|
110
|
+
sequence = 0;
|
|
111
|
+
reason = "";
|
|
112
|
+
actorRef = null;
|
|
113
|
+
/** History is corrected by appending another effective entry, never rewriting it. */
|
|
114
|
+
async save() {
|
|
115
|
+
if (this.id && await this.db.get(this.tableName, { id: this.id })) throw new Error("Legal member status history is append-only.");
|
|
116
|
+
this.requireInsertOnSave();
|
|
117
|
+
return super.save();
|
|
118
|
+
}
|
|
119
|
+
async delete() {
|
|
120
|
+
throw new Error("Legal member status history cannot be deleted.");
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
__publicField$6(LegalMemberStatusHistory, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
124
|
+
__decorateClass$6([tenantId()], LegalMemberStatusHistory.prototype, "tenantId", 2);
|
|
125
|
+
__decorateClass$6([foreignKey("LegalMember", { onDelete: "RESTRICT" })], LegalMemberStatusHistory.prototype, "memberId", 2);
|
|
126
|
+
__decorateClass$6([field({ type: "text" })], LegalMemberStatusHistory.prototype, "status", 2);
|
|
127
|
+
__decorateClass$6([field({ type: "text" })], LegalMemberStatusHistory.prototype, "effectiveOn", 2);
|
|
128
|
+
__decorateClass$6([field({ type: "integer" })], LegalMemberStatusHistory.prototype, "sequence", 2);
|
|
129
|
+
__decorateClass$6([field({
|
|
130
|
+
type: "text",
|
|
131
|
+
nullable: true
|
|
132
|
+
})], LegalMemberStatusHistory.prototype, "actorRef", 2);
|
|
133
|
+
LegalMemberStatusHistory = __decorateClass$6([TenantScoped({ mode: "required" }), smrt({
|
|
134
|
+
tableName: "legal_member_status_history",
|
|
135
|
+
sensitive: true,
|
|
136
|
+
indexes: [{
|
|
137
|
+
name: "legal_member_status_history_member_on_idx",
|
|
138
|
+
columns: [
|
|
139
|
+
"tenantId",
|
|
140
|
+
"memberId",
|
|
141
|
+
"effectiveOn"
|
|
142
|
+
]
|
|
143
|
+
}],
|
|
144
|
+
api: { include: [] },
|
|
145
|
+
mcp: { include: [] },
|
|
146
|
+
cli: false
|
|
147
|
+
})], LegalMemberStatusHistory);
|
|
148
|
+
var LegalMemberReference = class extends SmrtObject {
|
|
149
|
+
tenantId = "";
|
|
150
|
+
memberId = "";
|
|
151
|
+
kind = "share";
|
|
152
|
+
/** Qualified external model name or host namespace, e.g. @happyvertical/smrt-ledgers:JournalEntry. */
|
|
153
|
+
sourceType = "";
|
|
154
|
+
sourceId = "";
|
|
155
|
+
authoritative = false;
|
|
156
|
+
effectiveFrom = "";
|
|
157
|
+
effectiveTo = null;
|
|
158
|
+
revokesId = null;
|
|
159
|
+
async save() {
|
|
160
|
+
if (this.id && await this.db.get(this.tableName, { id: this.id })) throw new Error("Legal member references are append-only.");
|
|
161
|
+
this.requireInsertOnSave();
|
|
162
|
+
return super.save();
|
|
163
|
+
}
|
|
164
|
+
async delete() {
|
|
165
|
+
throw new Error("Legal member references cannot be deleted.");
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
__publicField$6(LegalMemberReference, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
169
|
+
__decorateClass$6([tenantId()], LegalMemberReference.prototype, "tenantId", 2);
|
|
170
|
+
__decorateClass$6([foreignKey("LegalMember", { onDelete: "RESTRICT" })], LegalMemberReference.prototype, "memberId", 2);
|
|
171
|
+
__decorateClass$6([field({ type: "text" })], LegalMemberReference.prototype, "kind", 2);
|
|
172
|
+
__decorateClass$6([field({ type: "boolean" })], LegalMemberReference.prototype, "authoritative", 2);
|
|
173
|
+
__decorateClass$6([field({ type: "text" })], LegalMemberReference.prototype, "effectiveFrom", 2);
|
|
174
|
+
__decorateClass$6([field({
|
|
175
|
+
type: "text",
|
|
176
|
+
nullable: true
|
|
177
|
+
})], LegalMemberReference.prototype, "effectiveTo", 2);
|
|
178
|
+
__decorateClass$6([foreignKey("LegalMemberReference", {
|
|
179
|
+
nullable: true,
|
|
180
|
+
onDelete: "RESTRICT"
|
|
181
|
+
})], LegalMemberReference.prototype, "revokesId", 2);
|
|
182
|
+
LegalMemberReference = __decorateClass$6([TenantScoped({ mode: "required" }), smrt({
|
|
183
|
+
tableName: "legal_member_references",
|
|
184
|
+
sensitive: true,
|
|
185
|
+
indexes: [{
|
|
186
|
+
name: "legal_member_references_member_kind_idx",
|
|
187
|
+
columns: [
|
|
188
|
+
"tenantId",
|
|
189
|
+
"memberId",
|
|
190
|
+
"kind"
|
|
191
|
+
]
|
|
192
|
+
}],
|
|
193
|
+
api: { include: [] },
|
|
194
|
+
mcp: { include: [] },
|
|
195
|
+
cli: false
|
|
196
|
+
})], LegalMemberReference);
|
|
197
|
+
var MemberOfficerAppointment = class extends SmrtObject {
|
|
198
|
+
tenantId = "";
|
|
199
|
+
memberId = "";
|
|
200
|
+
role = "";
|
|
201
|
+
effectiveFrom = "";
|
|
202
|
+
effectiveTo = null;
|
|
203
|
+
authority = null;
|
|
204
|
+
};
|
|
205
|
+
__publicField$6(MemberOfficerAppointment, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
206
|
+
__decorateClass$6([tenantId()], MemberOfficerAppointment.prototype, "tenantId", 2);
|
|
207
|
+
__decorateClass$6([foreignKey("LegalMember", { onDelete: "RESTRICT" })], MemberOfficerAppointment.prototype, "memberId", 2);
|
|
208
|
+
__decorateClass$6([field({ type: "text" })], MemberOfficerAppointment.prototype, "role", 2);
|
|
209
|
+
__decorateClass$6([field({ type: "text" })], MemberOfficerAppointment.prototype, "effectiveFrom", 2);
|
|
210
|
+
__decorateClass$6([field({
|
|
211
|
+
type: "text",
|
|
212
|
+
nullable: true
|
|
213
|
+
})], MemberOfficerAppointment.prototype, "effectiveTo", 2);
|
|
214
|
+
__decorateClass$6([field({
|
|
215
|
+
type: "json",
|
|
216
|
+
nullable: true
|
|
217
|
+
})], MemberOfficerAppointment.prototype, "authority", 2);
|
|
218
|
+
MemberOfficerAppointment = __decorateClass$6([TenantScoped({ mode: "required" }), smrt({
|
|
219
|
+
tableName: "member_officer_appointments",
|
|
220
|
+
sensitive: true,
|
|
221
|
+
indexes: [{
|
|
222
|
+
name: "member_officer_appointments_member_term_idx",
|
|
223
|
+
columns: [
|
|
224
|
+
"tenantId",
|
|
225
|
+
"memberId",
|
|
226
|
+
"effectiveFrom"
|
|
227
|
+
]
|
|
228
|
+
}],
|
|
229
|
+
api: { include: [] },
|
|
230
|
+
mcp: { include: [] },
|
|
231
|
+
cli: false
|
|
232
|
+
})], MemberOfficerAppointment);
|
|
233
|
+
var MemberEligibilitySnapshot = class extends SmrtObject {
|
|
234
|
+
tenantId = "";
|
|
235
|
+
memberId = "";
|
|
236
|
+
recordDate = "";
|
|
237
|
+
eligible = false;
|
|
238
|
+
reason = "";
|
|
239
|
+
evidence = null;
|
|
240
|
+
/** Record-date evidence is immutable; a later request creates a new snapshot. */
|
|
241
|
+
async save() {
|
|
242
|
+
if (this.id && await this.db.get(this.tableName, { id: this.id })) throw new Error("Member eligibility snapshots are immutable.");
|
|
243
|
+
this.requireInsertOnSave();
|
|
244
|
+
return super.save();
|
|
245
|
+
}
|
|
246
|
+
async delete() {
|
|
247
|
+
throw new Error("Member eligibility snapshots cannot be deleted.");
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
__publicField$6(MemberEligibilitySnapshot, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
251
|
+
__decorateClass$6([tenantId()], MemberEligibilitySnapshot.prototype, "tenantId", 2);
|
|
252
|
+
__decorateClass$6([foreignKey("LegalMember", { onDelete: "RESTRICT" })], MemberEligibilitySnapshot.prototype, "memberId", 2);
|
|
253
|
+
__decorateClass$6([field({ type: "text" })], MemberEligibilitySnapshot.prototype, "recordDate", 2);
|
|
254
|
+
__decorateClass$6([field({ type: "boolean" })], MemberEligibilitySnapshot.prototype, "eligible", 2);
|
|
255
|
+
__decorateClass$6([field({
|
|
256
|
+
type: "json",
|
|
257
|
+
nullable: true
|
|
258
|
+
})], MemberEligibilitySnapshot.prototype, "evidence", 2);
|
|
259
|
+
MemberEligibilitySnapshot = __decorateClass$6([TenantScoped({ mode: "required" }), smrt({
|
|
260
|
+
tableName: "member_eligibility_snapshots",
|
|
261
|
+
sensitive: true,
|
|
262
|
+
indexes: [{
|
|
263
|
+
name: "member_eligibility_snapshots_tenant_date_idx",
|
|
264
|
+
columns: ["tenantId", "recordDate"]
|
|
265
|
+
}],
|
|
266
|
+
api: { include: [] },
|
|
267
|
+
mcp: { include: [] },
|
|
268
|
+
cli: false
|
|
269
|
+
})], MemberEligibilitySnapshot);
|
|
270
|
+
var MemberClassCollection = class extends SmrtCollection {};
|
|
271
|
+
__publicField$6(MemberClassCollection, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
272
|
+
__publicField$6(MemberClassCollection, "_itemClass", MemberClass);
|
|
273
|
+
MemberClassCollection = __decorateClass$6([smrt({
|
|
274
|
+
api: { include: [] },
|
|
275
|
+
mcp: { include: [] },
|
|
276
|
+
cli: false
|
|
277
|
+
})], MemberClassCollection);
|
|
278
|
+
var LegalMemberCollection = class extends SmrtCollection {};
|
|
279
|
+
__publicField$6(LegalMemberCollection, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
280
|
+
__publicField$6(LegalMemberCollection, "_itemClass", LegalMember);
|
|
281
|
+
LegalMemberCollection = __decorateClass$6([smrt({
|
|
282
|
+
api: { include: [] },
|
|
283
|
+
mcp: { include: [] },
|
|
284
|
+
cli: false
|
|
285
|
+
})], LegalMemberCollection);
|
|
286
|
+
var LegalMemberStatusHistoryCollection = class extends SmrtCollection {};
|
|
287
|
+
__publicField$6(LegalMemberStatusHistoryCollection, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
288
|
+
__publicField$6(LegalMemberStatusHistoryCollection, "_itemClass", LegalMemberStatusHistory);
|
|
289
|
+
LegalMemberStatusHistoryCollection = __decorateClass$6([smrt({
|
|
290
|
+
api: { include: [] },
|
|
291
|
+
mcp: { include: [] },
|
|
292
|
+
cli: false
|
|
293
|
+
})], LegalMemberStatusHistoryCollection);
|
|
294
|
+
var LegalMemberReferenceCollection = class extends SmrtCollection {};
|
|
295
|
+
__publicField$6(LegalMemberReferenceCollection, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
296
|
+
__publicField$6(LegalMemberReferenceCollection, "_itemClass", LegalMemberReference);
|
|
297
|
+
LegalMemberReferenceCollection = __decorateClass$6([smrt({
|
|
298
|
+
api: { include: [] },
|
|
299
|
+
mcp: { include: [] },
|
|
300
|
+
cli: false
|
|
301
|
+
})], LegalMemberReferenceCollection);
|
|
302
|
+
var MemberOfficerAppointmentCollection = class extends SmrtCollection {};
|
|
303
|
+
__publicField$6(MemberOfficerAppointmentCollection, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
304
|
+
__publicField$6(MemberOfficerAppointmentCollection, "_itemClass", MemberOfficerAppointment);
|
|
305
|
+
MemberOfficerAppointmentCollection = __decorateClass$6([smrt({
|
|
306
|
+
api: { include: [] },
|
|
307
|
+
mcp: { include: [] },
|
|
308
|
+
cli: false
|
|
309
|
+
})], MemberOfficerAppointmentCollection);
|
|
310
|
+
var MemberEligibilitySnapshotCollection = class extends SmrtCollection {};
|
|
311
|
+
__publicField$6(MemberEligibilitySnapshotCollection, "__smrtPackage__", "@happyvertical/smrt-users");
|
|
312
|
+
__publicField$6(MemberEligibilitySnapshotCollection, "_itemClass", MemberEligibilitySnapshot);
|
|
313
|
+
MemberEligibilitySnapshotCollection = __decorateClass$6([smrt({
|
|
314
|
+
api: { include: [] },
|
|
315
|
+
mcp: { include: [] },
|
|
316
|
+
cli: false
|
|
317
|
+
})], MemberEligibilitySnapshotCollection);
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/member-register/service.ts
|
|
320
|
+
var ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
321
|
+
var MEMBER_STATUSES = [
|
|
322
|
+
"active",
|
|
323
|
+
"suspended",
|
|
324
|
+
"resigned",
|
|
325
|
+
"ceased"
|
|
326
|
+
];
|
|
327
|
+
var REFERENCE_KINDS = [
|
|
328
|
+
"share",
|
|
329
|
+
"dues",
|
|
330
|
+
"subscription",
|
|
331
|
+
"agreement",
|
|
332
|
+
"ledger"
|
|
333
|
+
];
|
|
334
|
+
function compareHistory(a, b) {
|
|
335
|
+
return a.effectiveOn.localeCompare(b.effectiveOn) || a.sequence - b.sequence;
|
|
336
|
+
}
|
|
337
|
+
function date(value, field) {
|
|
338
|
+
if (typeof value !== "string" || !ISO_DATE.test(value) || Number.isNaN(Date.parse(`${value}T00:00:00Z`))) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", `${field} must be YYYY-MM-DD.`);
|
|
339
|
+
if ((/* @__PURE__ */ new Date(`${value}T00:00:00.000Z`)).toISOString().slice(0, 10) !== value) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", `${field} must be a calendar date.`);
|
|
340
|
+
return value;
|
|
341
|
+
}
|
|
342
|
+
function text(value, field) {
|
|
343
|
+
if (typeof value !== "string" || !value.trim()) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", `${field} is required.`);
|
|
344
|
+
return value.trim();
|
|
345
|
+
}
|
|
346
|
+
var MemberRegisterError = class extends Error {
|
|
347
|
+
constructor(code, message) {
|
|
348
|
+
super(message);
|
|
349
|
+
this.code = code;
|
|
350
|
+
this.name = "MemberRegisterError";
|
|
351
|
+
}
|
|
352
|
+
code;
|
|
353
|
+
};
|
|
354
|
+
var MemberRegisterService = class MemberRegisterService {
|
|
355
|
+
constructor(db, actor, transactionBound) {
|
|
356
|
+
this.db = db;
|
|
357
|
+
this.actor = actor;
|
|
358
|
+
this.transactionBound = transactionBound;
|
|
359
|
+
text(actor?.tenantId, "tenantId");
|
|
360
|
+
}
|
|
361
|
+
db;
|
|
362
|
+
actor;
|
|
363
|
+
transactionBound;
|
|
364
|
+
static transactionToken = /* @__PURE__ */ Symbol("member-register-transaction");
|
|
365
|
+
transaction(operation) {
|
|
366
|
+
if (!this.db.transaction) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", "Member register writes require transaction support.");
|
|
367
|
+
return this.db.transaction((db) => operation(new MemberRegisterService(db, this.actor, MemberRegisterService.transactionToken)));
|
|
368
|
+
}
|
|
369
|
+
scope(run) {
|
|
370
|
+
const active = getTenantId();
|
|
371
|
+
if (active && active !== this.actor.tenantId) throw new MemberRegisterError("MEMBER_REGISTER_TENANT_MISMATCH", "Actor differs from active tenant.");
|
|
372
|
+
return withTenant({ tenantId: this.actor.tenantId }, run);
|
|
373
|
+
}
|
|
374
|
+
async member(memberId) {
|
|
375
|
+
const member = await (await LegalMemberCollection.create({ db: this.db })).get({
|
|
376
|
+
id: text(memberId, "memberId"),
|
|
377
|
+
tenantId: this.actor.tenantId
|
|
378
|
+
});
|
|
379
|
+
if (!member) throw new MemberRegisterError("MEMBER_REGISTER_NOT_FOUND", "Member not found in this tenant.");
|
|
380
|
+
return member;
|
|
381
|
+
}
|
|
382
|
+
assertReferenceKind(kind) {
|
|
383
|
+
if (!REFERENCE_KINDS.includes(kind)) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", "Unknown member reference kind.");
|
|
384
|
+
}
|
|
385
|
+
async addClass(input) {
|
|
386
|
+
return this.scope(async () => {
|
|
387
|
+
return await (await MemberClassCollection.create({ db: this.db })).create({
|
|
388
|
+
tenantId: this.actor.tenantId,
|
|
389
|
+
key: text(input.key, "key"),
|
|
390
|
+
name: text(input.name, "name"),
|
|
391
|
+
description: input.description?.trim() ?? "",
|
|
392
|
+
policyMetadata: input.policyMetadata ?? null
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
async enroll(input) {
|
|
397
|
+
if (this.transactionBound !== MemberRegisterService.transactionToken) {
|
|
398
|
+
const member = await this.transaction((service) => service.enroll(input));
|
|
399
|
+
return this.scope(() => this.member(member.id));
|
|
400
|
+
}
|
|
401
|
+
return this.scope(async () => {
|
|
402
|
+
const joinedOn = date(input.joinedOn, "joinedOn");
|
|
403
|
+
if (input.kind !== "individual" && input.kind !== "organisation") throw new MemberRegisterError("MEMBER_REGISTER_INVALID", "kind must be individual or organisation.");
|
|
404
|
+
const klass = await (await MemberClassCollection.create({ db: this.db })).get({
|
|
405
|
+
id: text(input.memberClassId, "memberClassId"),
|
|
406
|
+
tenantId: this.actor.tenantId
|
|
407
|
+
});
|
|
408
|
+
if (!klass) throw new MemberRegisterError("MEMBER_REGISTER_NOT_FOUND", "Member class not found in this tenant.");
|
|
409
|
+
if (input.profileId != null) {
|
|
410
|
+
const profiles = await ProfileCollection.create({ db: this.db });
|
|
411
|
+
const profile = (await withTenantGlobalRead(this.actor.tenantId, () => profiles.list({
|
|
412
|
+
where: { id: text(input.profileId, "profileId") },
|
|
413
|
+
limit: 1
|
|
414
|
+
})))[0];
|
|
415
|
+
if (!profile || profile.tenantId !== null && profile.tenantId !== this.actor.tenantId) throw new MemberRegisterError("MEMBER_REGISTER_NOT_FOUND", "Profile not found in this tenant or global scope.");
|
|
416
|
+
}
|
|
417
|
+
const member = await (await LegalMemberCollection.create({ db: this.db })).create({
|
|
418
|
+
tenantId: this.actor.tenantId,
|
|
419
|
+
memberClassId: klass.id,
|
|
420
|
+
kind: input.kind,
|
|
421
|
+
displayName: text(input.displayName, "displayName"),
|
|
422
|
+
joinedOn,
|
|
423
|
+
userId: input.userId ?? null,
|
|
424
|
+
profileId: input.profileId ?? null,
|
|
425
|
+
externalPartyRef: input.externalPartyRef?.trim() || null,
|
|
426
|
+
status: "active"
|
|
427
|
+
});
|
|
428
|
+
await (await LegalMemberStatusHistoryCollection.create({ db: this.db })).create({
|
|
429
|
+
tenantId: this.actor.tenantId,
|
|
430
|
+
memberId: member.id,
|
|
431
|
+
status: "active",
|
|
432
|
+
effectiveOn: joinedOn,
|
|
433
|
+
sequence: 1,
|
|
434
|
+
reason: "joined",
|
|
435
|
+
actorRef: this.actor.actorRef ?? null
|
|
436
|
+
});
|
|
437
|
+
return member;
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
async setStatus(memberId, input) {
|
|
441
|
+
if (this.transactionBound !== MemberRegisterService.transactionToken) {
|
|
442
|
+
const member = await this.transaction((service) => service.setStatus(memberId, input));
|
|
443
|
+
return this.scope(() => this.member(member.id));
|
|
444
|
+
}
|
|
445
|
+
return this.scope(async () => {
|
|
446
|
+
const member = await this.member(memberId);
|
|
447
|
+
const effectiveOn = date(input.effectiveOn, "effectiveOn");
|
|
448
|
+
if (!MEMBER_STATUSES.includes(input.status)) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", "Unknown member status.");
|
|
449
|
+
const histories = await LegalMemberStatusHistoryCollection.create({ db: this.db });
|
|
450
|
+
const prior = await histories.list({ where: {
|
|
451
|
+
tenantId: this.actor.tenantId,
|
|
452
|
+
memberId: member.id
|
|
453
|
+
} });
|
|
454
|
+
await histories.create({
|
|
455
|
+
tenantId: this.actor.tenantId,
|
|
456
|
+
memberId: member.id,
|
|
457
|
+
status: input.status,
|
|
458
|
+
effectiveOn,
|
|
459
|
+
sequence: Math.max(0, ...prior.map((entry) => entry.sequence ?? 0)) + 1,
|
|
460
|
+
reason: input.reason?.trim() ?? "",
|
|
461
|
+
actorRef: this.actor.actorRef ?? null
|
|
462
|
+
});
|
|
463
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
464
|
+
const current = (await histories.list({ where: {
|
|
465
|
+
tenantId: this.actor.tenantId,
|
|
466
|
+
memberId: member.id
|
|
467
|
+
} })).filter((entry) => entry.effectiveOn <= today).sort(compareHistory).at(-1);
|
|
468
|
+
member.status = current?.status ?? "active";
|
|
469
|
+
member.leftOn = current?.status === "resigned" || current?.status === "ceased" ? current.effectiveOn : null;
|
|
470
|
+
await member.save();
|
|
471
|
+
return member;
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
async addReference(memberId, input) {
|
|
475
|
+
return this.scope(async () => {
|
|
476
|
+
const member = await this.member(memberId);
|
|
477
|
+
this.assertReferenceKind(input.kind);
|
|
478
|
+
const effectiveFrom = date(input.effectiveFrom, "effectiveFrom");
|
|
479
|
+
const effectiveTo = input.effectiveTo == null ? null : date(input.effectiveTo, "effectiveTo");
|
|
480
|
+
if (effectiveTo && effectiveTo < effectiveFrom) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", "effectiveTo must not precede effectiveFrom.");
|
|
481
|
+
return await (await LegalMemberReferenceCollection.create({ db: this.db })).create({
|
|
482
|
+
tenantId: this.actor.tenantId,
|
|
483
|
+
memberId: member.id,
|
|
484
|
+
kind: input.kind,
|
|
485
|
+
sourceType: text(input.sourceType, "sourceType"),
|
|
486
|
+
sourceId: text(input.sourceId, "sourceId"),
|
|
487
|
+
authoritative: input.authoritative === true,
|
|
488
|
+
effectiveFrom,
|
|
489
|
+
effectiveTo
|
|
490
|
+
});
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
/** Append a dated withdrawal without changing past evidence or snapshots. */
|
|
494
|
+
async revokeReference(referenceId, input) {
|
|
495
|
+
return this.scope(async () => {
|
|
496
|
+
const refs = await LegalMemberReferenceCollection.create({ db: this.db });
|
|
497
|
+
const reference = await refs.get({
|
|
498
|
+
id: text(referenceId, "referenceId"),
|
|
499
|
+
tenantId: this.actor.tenantId
|
|
500
|
+
});
|
|
501
|
+
if (!reference) throw new MemberRegisterError("MEMBER_REGISTER_NOT_FOUND", "Reference not found in this tenant.");
|
|
502
|
+
const effectiveFrom = date(input.effectiveOn, "effectiveOn");
|
|
503
|
+
if (reference.revokesId || effectiveFrom < reference.effectiveFrom) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", "Revoke original evidence on or after its effectiveFrom date.");
|
|
504
|
+
return refs.create({
|
|
505
|
+
tenantId: this.actor.tenantId,
|
|
506
|
+
memberId: reference.memberId,
|
|
507
|
+
kind: reference.kind,
|
|
508
|
+
sourceType: reference.sourceType,
|
|
509
|
+
sourceId: reference.sourceId,
|
|
510
|
+
authoritative: false,
|
|
511
|
+
effectiveFrom,
|
|
512
|
+
revokesId: reference.id
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
async appoint(memberId, input) {
|
|
517
|
+
return this.scope(async () => {
|
|
518
|
+
const member = await this.member(memberId);
|
|
519
|
+
const from = date(input.effectiveFrom, "effectiveFrom");
|
|
520
|
+
const to = input.effectiveTo == null ? null : date(input.effectiveTo, "effectiveTo");
|
|
521
|
+
if (to && to < from) throw new MemberRegisterError("MEMBER_REGISTER_INVALID", "effectiveTo must not precede effectiveFrom.");
|
|
522
|
+
return await (await MemberOfficerAppointmentCollection.create({ db: this.db })).create({
|
|
523
|
+
tenantId: this.actor.tenantId,
|
|
524
|
+
memberId: member.id,
|
|
525
|
+
role: text(input.role, "role"),
|
|
526
|
+
effectiveFrom: from,
|
|
527
|
+
effectiveTo: to,
|
|
528
|
+
authority: input.authority ?? null
|
|
529
|
+
});
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
async asOf(recordDate, policy = {}) {
|
|
533
|
+
if (this.transactionBound !== MemberRegisterService.transactionToken) return this.transaction((service) => service.asOf(recordDate, policy));
|
|
534
|
+
return this.scope(async () => {
|
|
535
|
+
const on = date(recordDate, "recordDate");
|
|
536
|
+
const memberClassKeys = policy.memberClassKeys === void 0 ? null : [...policy.memberClassKeys];
|
|
537
|
+
const statuses = [...policy.statuses ?? ["active"]];
|
|
538
|
+
const requiredAuthoritativeKinds = [...policy.requireAuthoritativeKinds ?? []];
|
|
539
|
+
const members = await LegalMemberCollection.create({ db: this.db });
|
|
540
|
+
const classes = await MemberClassCollection.create({ db: this.db });
|
|
541
|
+
const histories = await LegalMemberStatusHistoryCollection.create({ db: this.db });
|
|
542
|
+
const refs = await LegalMemberReferenceCollection.create({ db: this.db });
|
|
543
|
+
const snapshots = await MemberEligibilitySnapshotCollection.create({ db: this.db });
|
|
544
|
+
const rows = [];
|
|
545
|
+
for (const member of await members.list({ where: { tenantId: this.actor.tenantId } })) {
|
|
546
|
+
const klass = await classes.get({
|
|
547
|
+
id: member.memberClassId,
|
|
548
|
+
tenantId: this.actor.tenantId
|
|
549
|
+
});
|
|
550
|
+
const status = (await histories.list({ where: {
|
|
551
|
+
tenantId: this.actor.tenantId,
|
|
552
|
+
memberId: member.id
|
|
553
|
+
} })).filter((entry) => entry.effectiveOn <= on).sort(compareHistory).at(-1)?.status;
|
|
554
|
+
const allRefs = await refs.list({ where: {
|
|
555
|
+
tenantId: this.actor.tenantId,
|
|
556
|
+
memberId: member.id
|
|
557
|
+
} });
|
|
558
|
+
const revoked = new Set(allRefs.filter((reference) => reference.revokesId && reference.effectiveFrom <= on).map((reference) => reference.revokesId));
|
|
559
|
+
const memberRefs = allRefs.filter((reference) => !reference.revokesId && !revoked.has(reference.id) && reference.effectiveFrom <= on && (reference.effectiveTo === null || reference.effectiveTo >= on));
|
|
560
|
+
const missing = requiredAuthoritativeKinds.filter((kind) => !memberRefs.some((reference) => reference.kind === kind && reference.authoritative));
|
|
561
|
+
const classOK = memberClassKeys === null || !!klass && memberClassKeys.includes(klass.key);
|
|
562
|
+
const statusOK = !!status && statuses.includes(status);
|
|
563
|
+
const eligible = member.joinedOn <= on && classOK && statusOK && missing.length === 0;
|
|
564
|
+
const reason = missing.length ? `authoritative evidence unavailable: ${missing.join(", ")}` : !classOK ? "member class excluded by policy" : !statusOK ? `status ${status ?? "unrecorded"} excluded by policy` : member.joinedOn > on ? "joined after record date" : "eligible";
|
|
565
|
+
const evidence = {
|
|
566
|
+
status,
|
|
567
|
+
memberClassKeys,
|
|
568
|
+
statuses,
|
|
569
|
+
requiredAuthoritativeKinds,
|
|
570
|
+
missingAuthoritativeKinds: missing,
|
|
571
|
+
referenceCount: memberRefs.length
|
|
572
|
+
};
|
|
573
|
+
const row = {
|
|
574
|
+
memberId: member.id,
|
|
575
|
+
displayName: member.displayName,
|
|
576
|
+
memberClassKey: klass?.key ?? "",
|
|
577
|
+
recordDate: on,
|
|
578
|
+
eligible,
|
|
579
|
+
reason,
|
|
580
|
+
evidence
|
|
581
|
+
};
|
|
582
|
+
await snapshots.create({
|
|
583
|
+
tenantId: this.actor.tenantId,
|
|
584
|
+
memberId: row.memberId,
|
|
585
|
+
recordDate: on,
|
|
586
|
+
eligible,
|
|
587
|
+
reason,
|
|
588
|
+
evidence
|
|
589
|
+
});
|
|
590
|
+
rows.push(row);
|
|
591
|
+
}
|
|
592
|
+
return rows;
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
static exportJson(rows) {
|
|
596
|
+
return JSON.stringify(rows);
|
|
597
|
+
}
|
|
598
|
+
static exportCsv(rows) {
|
|
599
|
+
const q = (value) => {
|
|
600
|
+
const text2 = String(value ?? "");
|
|
601
|
+
return `"${(/^[=+\-@]/.test(text2) ? `'${text2}` : text2).replaceAll("\"", "\"\"")}"`;
|
|
602
|
+
};
|
|
603
|
+
return `${["memberId,displayName,memberClassKey,recordDate,eligible,reason", ...rows.map((row) => [
|
|
604
|
+
row.memberId,
|
|
605
|
+
row.displayName,
|
|
606
|
+
row.memberClassKey,
|
|
607
|
+
row.recordDate,
|
|
608
|
+
row.eligible,
|
|
609
|
+
row.reason
|
|
610
|
+
].map(q).join(","))].join("\n")}
|
|
611
|
+
`;
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
//#endregion
|
|
11
615
|
//#region src/models/ResourceGrant.ts
|
|
12
616
|
var __defProp$5 = Object.defineProperty;
|
|
13
617
|
var __getOwnPropDesc$5 = Object.getOwnPropertyDescriptor;
|
|
@@ -1948,7 +2552,7 @@ var MagicLinkService = class MagicLinkService {
|
|
|
1948
2552
|
* The caller is responsible for emailing the token to the user.
|
|
1949
2553
|
*/
|
|
1950
2554
|
async generate(email) {
|
|
1951
|
-
const { SignJWT } = await import("./chunks/TerminalAuthService-
|
|
2555
|
+
const { SignJWT } = await import("./chunks/TerminalAuthService-BBWemruU.js").then((n) => n.V);
|
|
1952
2556
|
const key = await this.getSigningKey();
|
|
1953
2557
|
const nonce = crypto.randomUUID();
|
|
1954
2558
|
const normalizedEmail = normalizeEmail(email);
|
|
@@ -1977,7 +2581,7 @@ var MagicLinkService = class MagicLinkService {
|
|
|
1977
2581
|
* @throws {MagicLinkError} If the token is invalid, expired, or already used
|
|
1978
2582
|
*/
|
|
1979
2583
|
async verify(token) {
|
|
1980
|
-
const { jwtVerify, errors } = await import("./chunks/TerminalAuthService-
|
|
2584
|
+
const { jwtVerify, errors } = await import("./chunks/TerminalAuthService-BBWemruU.js").then((n) => n.V);
|
|
1981
2585
|
const key = await this.getSigningKey();
|
|
1982
2586
|
let payload;
|
|
1983
2587
|
try {
|
|
@@ -2973,6 +3577,6 @@ var TenantService = class TenantService {
|
|
|
2973
3577
|
//#region src/index.ts
|
|
2974
3578
|
registerUserRetentionTasks();
|
|
2975
3579
|
//#endregion
|
|
2976
|
-
export { ACCESS_REQUEST_CAPABILITIES, ANCESTOR_READ_ACTION, AccessRequest, AccessRequestCollection, AccessRequestError, AccessRequestService, AccessRequestStatus, CLI_AUTH_RETENTION_TASK, UsersCliAuthRequest as CliAuthRequest, UsersCliAuthRequest, UsersCliAuthRequestCollection as CliAuthRequestCollection, UsersCliAuthRequestCollection, DEFAULT_ANCESTOR_READ_MAX_DEPTH, DEFAULT_CLI_AUTH_POLL_INTERVAL_SECONDS, DEFAULT_CLI_AUTH_REQUEST_TTL_SECONDS, DEFAULT_CLI_SESSION_TTL_SECONDS, DEFAULT_DEVICE_PERSON_IDLE_SECONDS, DEFAULT_LOGIN_ATTEMPT_WINDOW_SECONDS, DEFAULT_LOGIN_AUDIT_RETENTION_DAYS, DEFAULT_LOGIN_LOCKOUT_BASE_SECONDS, DEFAULT_LOGIN_LOCKOUT_FACTOR, DEFAULT_LOGIN_LOCKOUT_MAX_SECONDS, DEFAULT_LOGIN_MAX_ATTEMPTS, DEFAULT_PASSWORD_DENYLIST, DEFAULT_PASSWORD_MANAGE_PERMISSION, DEFAULT_PASSWORD_MAX_LENGTH, DEFAULT_PASSWORD_MIN_LENGTH, DEFAULT_PASSWORD_RECOVERY_MAX_AGE_SECONDS, DEFAULT_PIN_MANAGE_PERMISSION, DEFAULT_ROLES, DEFAULT_ROLE_PERMISSION_PATTERNS, DEFAULT_ROLE_SLUGS, DEFAULT_SESSION_TTL, DEFAULT_SOURCE_LOCKOUT_AUDIT_SECONDS, DEFAULT_TENANT_POLICY, DEFAULT_TOKEN_EXPIRY_SECONDS, DeviceCredentialError, DeviceCredentialForbiddenError, DeviceCredentialPolicyError, DeviceCredentialService, DurableLoginAuditSink, Group, GroupCollection, GroupMember, GroupMemberCollection, GroupRole, GroupRoleCollection, InvalidCredentialsError, LEGACY_USER_PROFILE_BACKFILL_NAME, LOGIN_ATTEMPTS_RETENTION_TASK, LOGIN_AUDIT_RETENTION_TASK, LegacyUserProfileBackfillError, LoginAttemptLimiter, LoginRateLimitError, MAGIC_LINK_RETENTION_TASK, MAX_RESOURCE_GRANT_DELEGATION_DEPTH, MAX_TENANT_HIERARCHY_DEPTH, MagicLinkError, MagicLinkService, UsersMagicLinkToken as MagicLinkToken, UsersMagicLinkToken, UsersMagicLinkTokenCollection as MagicLinkTokenCollection, UsersMagicLinkTokenCollection, Membership, MembershipCollection, MembershipOverride, MembershipOverrideCollection, MembershipStatus, MobileAuthError, MobileAuthService, OAUTH_CREDENTIALS_RETENTION_TASK, OidcLoginError, OidcLoginService, OidcProvisioningError, OperationPermissionError, OverrideEffect, PASSWORD_LOGIN_KIND, PASSWORD_MAX_LENGTH_CEILING, PASSWORD_PERMISSION_DEFINITIONS, PASSWORD_RECOVERY_MAX_AGE_CEILING_SECONDS, PIN_LOGIN_KIND, PIN_PERMISSION_DEFINITIONS, PasswordCredentialError, PasswordCredentialForbiddenError, PasswordCredentialService, PasswordPolicyError, Permission, PermissionCatalogService, PermissionCollection, PermissionResolver, PinVerifier, ResourceGrant, ResourceGrantCollection, ResourceGrantService, Role, RoleCollection, RolePermission, RolePermissionCollection, SESSIONS_RETENTION_TASK, SESSION_DATA_KEYS, SMRT_OAUTH_GRANT_CLAIM, Session, SessionCollection, SessionService, SessionStatus, SmrtOAuthAuthorizationService, SmrtOAuthAuthorizationStorage, TERMINAL_APPROVE_LOGIN_KIND, Tenant, TenantCollection, TenantHierarchyError, TenantHierarchyMaterializationError, TenantIntegration, TenantIntegrationCollection, TenantPermissionEffect, TenantPermissionOverride, TenantPermissionOverrideCollection, TenantService, TenantStatus, TerminalAuthError, TerminalAuthRateLimitError, TerminalAuthService, USER_RETENTION_TASKS, User, UserCollection, UserEmailKeyBackfillError, UserStatus, UsersCliAuthApproveLimit, UsersCliAuthApproveLimitCollection, UsersLoginAttempt, UsersLoginAttemptCollection, UsersLoginAuditEvent, UsersLoginAuditEventCollection, UsersOAuthAccessTokenRevocation, UsersOAuthAccessTokenRevocationCollection, UsersOAuthAuthorization, UsersOAuthAuthorizationCode, UsersOAuthAuthorizationCodeCollection, UsersOAuthAuthorizationCollection, UsersOAuthClient, UsersOAuthClientCollection, UsersOAuthRefreshFamily, UsersOAuthRefreshFamilyCollection, UsersOAuthRefreshGrant, UsersOAuthRefreshGrantCollection, UsersPasswordCredential, UsersPasswordCredentialCollection, UsersPinCredential, UsersPinCredentialCollection, UsersRolesAndPermissionsRecipe, UsersSignInRecipe, applyPostgresPermissionPolicies, assertOperationPermission, backfillLegacyUserProfiles, backfillUserEmailKeys, checkOperationPermission, checkResourceOperationPermission, decodeOidcTransaction, deduplicateAuthorityPairs, deduplicateRolePermissions, deriveOperationPermissionCollectionName, deriveOperationPermissionSlug, encodeOidcTransaction, ensurePasswordPermissionsRegistered, ensurePinPermissionsRegistered, generatePostgresPermissionSql, generateSessionId, getConfiguredAncestorReadPolicy, getCurrentSessionPermissionContext, getRequestScopedDatabase, getUsersOidcConfig, hasOperationPermission, isAncestorReadableSlug, materializeTenantHierarchy, normalizeAncestorReadPolicy, normalizeOperationPermissionAction, outOfBandProofSessionData, planTenantHierarchy, readMobileBearerToken, registerPermissionDefinitions, registerUserRetentionTasks, resolveOidcProviderConfig, syncPermissionCatalog, unregisterUserRetentionTasks, validateMobileRedirectUri, withPrincipalPermissionContext, withSessionPermissionContext };
|
|
3580
|
+
export { ACCESS_REQUEST_CAPABILITIES, ANCESTOR_READ_ACTION, AccessRequest, AccessRequestCollection, AccessRequestError, AccessRequestService, AccessRequestStatus, CLI_AUTH_RETENTION_TASK, UsersCliAuthRequest as CliAuthRequest, UsersCliAuthRequest, UsersCliAuthRequestCollection as CliAuthRequestCollection, UsersCliAuthRequestCollection, DEFAULT_ANCESTOR_READ_MAX_DEPTH, DEFAULT_CLI_AUTH_POLL_INTERVAL_SECONDS, DEFAULT_CLI_AUTH_REQUEST_TTL_SECONDS, DEFAULT_CLI_SESSION_TTL_SECONDS, DEFAULT_DEVICE_PERSON_IDLE_SECONDS, DEFAULT_LOGIN_ATTEMPT_WINDOW_SECONDS, DEFAULT_LOGIN_AUDIT_RETENTION_DAYS, DEFAULT_LOGIN_LOCKOUT_BASE_SECONDS, DEFAULT_LOGIN_LOCKOUT_FACTOR, DEFAULT_LOGIN_LOCKOUT_MAX_SECONDS, DEFAULT_LOGIN_MAX_ATTEMPTS, DEFAULT_PASSWORD_DENYLIST, DEFAULT_PASSWORD_MANAGE_PERMISSION, DEFAULT_PASSWORD_MAX_LENGTH, DEFAULT_PASSWORD_MIN_LENGTH, DEFAULT_PASSWORD_RECOVERY_MAX_AGE_SECONDS, DEFAULT_PIN_MANAGE_PERMISSION, DEFAULT_ROLES, DEFAULT_ROLE_PERMISSION_PATTERNS, DEFAULT_ROLE_SLUGS, DEFAULT_SESSION_TTL, DEFAULT_SOURCE_LOCKOUT_AUDIT_SECONDS, DEFAULT_TENANT_POLICY, DEFAULT_TOKEN_EXPIRY_SECONDS, DeviceCredentialError, DeviceCredentialForbiddenError, DeviceCredentialPolicyError, DeviceCredentialService, DurableLoginAuditSink, Group, GroupCollection, GroupMember, GroupMemberCollection, GroupRole, GroupRoleCollection, InvalidCredentialsError, LEGACY_USER_PROFILE_BACKFILL_NAME, LOGIN_ATTEMPTS_RETENTION_TASK, LOGIN_AUDIT_RETENTION_TASK, LegacyUserProfileBackfillError, LegalMember, LegalMemberCollection, LegalMemberReference, LegalMemberReferenceCollection, LegalMemberStatusHistory, LegalMemberStatusHistoryCollection, LoginAttemptLimiter, LoginRateLimitError, MAGIC_LINK_RETENTION_TASK, MAX_RESOURCE_GRANT_DELEGATION_DEPTH, MAX_TENANT_HIERARCHY_DEPTH, MagicLinkError, MagicLinkService, UsersMagicLinkToken as MagicLinkToken, UsersMagicLinkToken, UsersMagicLinkTokenCollection as MagicLinkTokenCollection, UsersMagicLinkTokenCollection, MemberClass, MemberClassCollection, MemberEligibilitySnapshot, MemberEligibilitySnapshotCollection, MemberOfficerAppointment, MemberOfficerAppointmentCollection, MemberRegisterError, MemberRegisterService, Membership, MembershipCollection, MembershipOverride, MembershipOverrideCollection, MembershipStatus, MobileAuthError, MobileAuthService, OAUTH_CREDENTIALS_RETENTION_TASK, OidcLoginError, OidcLoginService, OidcProvisioningError, OperationPermissionError, OverrideEffect, PASSWORD_LOGIN_KIND, PASSWORD_MAX_LENGTH_CEILING, PASSWORD_PERMISSION_DEFINITIONS, PASSWORD_RECOVERY_MAX_AGE_CEILING_SECONDS, PIN_LOGIN_KIND, PIN_PERMISSION_DEFINITIONS, PasswordCredentialError, PasswordCredentialForbiddenError, PasswordCredentialService, PasswordPolicyError, Permission, PermissionCatalogService, PermissionCollection, PermissionResolver, PinVerifier, ResourceGrant, ResourceGrantCollection, ResourceGrantService, Role, RoleCollection, RolePermission, RolePermissionCollection, SESSIONS_RETENTION_TASK, SESSION_DATA_KEYS, SMRT_OAUTH_GRANT_CLAIM, Session, SessionCollection, SessionService, SessionStatus, SmrtOAuthAuthorizationService, SmrtOAuthAuthorizationStorage, TERMINAL_APPROVE_LOGIN_KIND, Tenant, TenantCollection, TenantHierarchyError, TenantHierarchyMaterializationError, TenantIntegration, TenantIntegrationCollection, TenantPermissionEffect, TenantPermissionOverride, TenantPermissionOverrideCollection, TenantService, TenantStatus, TerminalAuthError, TerminalAuthRateLimitError, TerminalAuthService, USER_RETENTION_TASKS, User, UserCollection, UserEmailKeyBackfillError, UserStatus, UsersCliAuthApproveLimit, UsersCliAuthApproveLimitCollection, UsersLoginAttempt, UsersLoginAttemptCollection, UsersLoginAuditEvent, UsersLoginAuditEventCollection, UsersOAuthAccessTokenRevocation, UsersOAuthAccessTokenRevocationCollection, UsersOAuthAuthorization, UsersOAuthAuthorizationCode, UsersOAuthAuthorizationCodeCollection, UsersOAuthAuthorizationCollection, UsersOAuthClient, UsersOAuthClientCollection, UsersOAuthRefreshFamily, UsersOAuthRefreshFamilyCollection, UsersOAuthRefreshGrant, UsersOAuthRefreshGrantCollection, UsersPasswordCredential, UsersPasswordCredentialCollection, UsersPinCredential, UsersPinCredentialCollection, UsersRolesAndPermissionsRecipe, UsersSignInRecipe, applyPostgresPermissionPolicies, assertOperationPermission, backfillLegacyUserProfiles, backfillUserEmailKeys, checkOperationPermission, checkResourceOperationPermission, decodeOidcTransaction, deduplicateAuthorityPairs, deduplicateRolePermissions, deriveOperationPermissionCollectionName, deriveOperationPermissionSlug, encodeOidcTransaction, ensurePasswordPermissionsRegistered, ensurePinPermissionsRegistered, generatePostgresPermissionSql, generateSessionId, getConfiguredAncestorReadPolicy, getCurrentSessionPermissionContext, getRequestScopedDatabase, getUsersOidcConfig, hasOperationPermission, isAncestorReadableSlug, materializeTenantHierarchy, normalizeAncestorReadPolicy, normalizeOperationPermissionAction, outOfBandProofSessionData, planTenantHierarchy, readMobileBearerToken, registerPermissionDefinitions, registerUserRetentionTasks, resolveOidcProviderConfig, syncPermissionCatalog, unregisterUserRetentionTasks, validateMobileRedirectUri, withPrincipalPermissionContext, withSessionPermissionContext };
|
|
2977
3581
|
|
|
2978
3582
|
//# sourceMappingURL=index.js.map
|