@happyvertical/smrt-users 0.55.22 → 0.55.24
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/AGENTS.md +8 -0
- package/README.md +129 -0
- package/agents/permissions.md +8 -0
- package/dist/chunks/{TerminalAuthService-BHqR0fQH.js → TerminalAuthService-B0icE2mR.js} +282 -116
- package/dist/chunks/TerminalAuthService-B0icE2mR.js.map +1 -0
- package/dist/collections/GroupMemberCollection.d.ts +6 -2
- package/dist/collections/GroupMemberCollection.d.ts.map +1 -1
- package/dist/collections/MembershipOverrideCollection.d.ts +9 -2
- package/dist/collections/MembershipOverrideCollection.d.ts.map +1 -1
- package/dist/collections/TenantPermissionOverrideCollection.d.ts +8 -2
- package/dist/collections/TenantPermissionOverrideCollection.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -29
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +75 -45
- package/dist/migrations/deduplicateAuthorityPairs.d.ts +27 -0
- package/dist/migrations/deduplicateAuthorityPairs.d.ts.map +1 -0
- package/dist/migrations/deduplicateRolePermissions.d.ts +3 -10
- package/dist/migrations/deduplicateRolePermissions.d.ts.map +1 -1
- package/dist/migrations/natural-key-dedup.d.ts +32 -0
- package/dist/migrations/natural-key-dedup.d.ts.map +1 -0
- package/dist/models/GroupMember.d.ts.map +1 -1
- package/dist/models/LoginAuditEvent.d.ts +5 -0
- package/dist/models/LoginAuditEvent.d.ts.map +1 -1
- package/dist/models/MembershipOverride.d.ts.map +1 -1
- package/dist/models/Session.d.ts +9 -0
- package/dist/models/Session.d.ts.map +1 -1
- package/dist/models/TenantPermissionOverride.d.ts.map +1 -1
- package/dist/services/LoginAttemptLimiter.d.ts +62 -11
- package/dist/services/LoginAttemptLimiter.d.ts.map +1 -1
- package/dist/services/PasswordCredentialService.d.ts +83 -1
- package/dist/services/PasswordCredentialService.d.ts.map +1 -1
- package/dist/services/index.d.ts +2 -2
- package/dist/services/index.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +16 -9
- package/dist/sveltekit/password-handlers.d.ts +7 -0
- package/dist/sveltekit/password-handlers.d.ts.map +1 -1
- package/dist/sveltekit.js +13 -1
- package/dist/sveltekit.js.map +1 -1
- package/package.json +13 -13
- package/dist/chunks/TerminalAuthService-BHqR0fQH.js.map +0 -1
package/dist/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": "1.0.0",
|
|
3
3
|
"timestamp": 0,
|
|
4
4
|
"packageName": "@happyvertical/smrt-users",
|
|
5
|
-
"packageVersion": "0.55.
|
|
5
|
+
"packageVersion": "0.55.24",
|
|
6
6
|
"objects": {
|
|
7
7
|
"@happyvertical/smrt-users:AccessRequestCollection": {
|
|
8
8
|
"name": "accessrequestcollection",
|
|
@@ -878,23 +878,24 @@
|
|
|
878
878
|
},
|
|
879
879
|
"indexes": [
|
|
880
880
|
{
|
|
881
|
-
"name": "
|
|
881
|
+
"name": "group_members_group_id_user_id_idx",
|
|
882
882
|
"columns": [
|
|
883
|
-
"
|
|
884
|
-
"
|
|
883
|
+
"group_id",
|
|
884
|
+
"user_id"
|
|
885
885
|
],
|
|
886
886
|
"unique": true
|
|
887
887
|
},
|
|
888
888
|
{
|
|
889
|
-
"name": "
|
|
889
|
+
"name": "group_members_slug_context_idx",
|
|
890
890
|
"columns": [
|
|
891
|
-
"
|
|
891
|
+
"slug",
|
|
892
|
+
"context"
|
|
892
893
|
]
|
|
893
894
|
},
|
|
894
895
|
{
|
|
895
|
-
"name": "
|
|
896
|
+
"name": "group_members_created_at_idx",
|
|
896
897
|
"columns": [
|
|
897
|
-
"
|
|
898
|
+
"created_at"
|
|
898
899
|
]
|
|
899
900
|
},
|
|
900
901
|
{
|
|
@@ -2051,23 +2052,24 @@
|
|
|
2051
2052
|
},
|
|
2052
2053
|
"indexes": [
|
|
2053
2054
|
{
|
|
2054
|
-
"name": "
|
|
2055
|
+
"name": "membership_overrides_membership_id_permission_id_idx",
|
|
2055
2056
|
"columns": [
|
|
2056
|
-
"
|
|
2057
|
-
"
|
|
2057
|
+
"membership_id",
|
|
2058
|
+
"permission_id"
|
|
2058
2059
|
],
|
|
2059
2060
|
"unique": true
|
|
2060
2061
|
},
|
|
2061
2062
|
{
|
|
2062
|
-
"name": "
|
|
2063
|
+
"name": "membership_overrides_slug_context_idx",
|
|
2063
2064
|
"columns": [
|
|
2064
|
-
"
|
|
2065
|
+
"slug",
|
|
2066
|
+
"context"
|
|
2065
2067
|
]
|
|
2066
2068
|
},
|
|
2067
2069
|
{
|
|
2068
|
-
"name": "
|
|
2070
|
+
"name": "membership_overrides_created_at_idx",
|
|
2069
2071
|
"columns": [
|
|
2070
|
-
"
|
|
2072
|
+
"created_at"
|
|
2071
2073
|
]
|
|
2072
2074
|
},
|
|
2073
2075
|
{
|
|
@@ -5472,14 +5474,20 @@
|
|
|
5472
5474
|
},
|
|
5473
5475
|
"indexes": [
|
|
5474
5476
|
{
|
|
5475
|
-
"name": "
|
|
5477
|
+
"name": "tenant_permission_overrides_tenant_id_permission_id_idx",
|
|
5476
5478
|
"columns": [
|
|
5477
5479
|
"tenant_id",
|
|
5478
|
-
"
|
|
5479
|
-
"context"
|
|
5480
|
+
"permission_id"
|
|
5480
5481
|
],
|
|
5481
5482
|
"unique": true
|
|
5482
5483
|
},
|
|
5484
|
+
{
|
|
5485
|
+
"name": "tenant_permission_overrides_slug_context_idx",
|
|
5486
|
+
"columns": [
|
|
5487
|
+
"slug",
|
|
5488
|
+
"context"
|
|
5489
|
+
]
|
|
5490
|
+
},
|
|
5483
5491
|
{
|
|
5484
5492
|
"name": "tenant_permission_overrides_created_at_idx",
|
|
5485
5493
|
"columns": [
|
|
@@ -6543,7 +6551,8 @@
|
|
|
6543
6551
|
"required": true,
|
|
6544
6552
|
"related": "Group",
|
|
6545
6553
|
"_meta": {
|
|
6546
|
-
"required": true
|
|
6554
|
+
"required": true,
|
|
6555
|
+
"onDelete": "NO ACTION"
|
|
6547
6556
|
}
|
|
6548
6557
|
},
|
|
6549
6558
|
"userId": {
|
|
@@ -6551,7 +6560,8 @@
|
|
|
6551
6560
|
"required": true,
|
|
6552
6561
|
"related": "User",
|
|
6553
6562
|
"_meta": {
|
|
6554
|
-
"required": true
|
|
6563
|
+
"required": true,
|
|
6564
|
+
"onDelete": "NO ACTION"
|
|
6555
6565
|
}
|
|
6556
6566
|
}
|
|
6557
6567
|
},
|
|
@@ -6574,7 +6584,11 @@
|
|
|
6574
6584
|
"list",
|
|
6575
6585
|
"get"
|
|
6576
6586
|
]
|
|
6577
|
-
}
|
|
6587
|
+
},
|
|
6588
|
+
"conflictColumns": [
|
|
6589
|
+
"group_id",
|
|
6590
|
+
"user_id"
|
|
6591
|
+
]
|
|
6578
6592
|
},
|
|
6579
6593
|
"extends": "SmrtObject",
|
|
6580
6594
|
"exportName": "GroupMember",
|
|
@@ -6647,23 +6661,24 @@
|
|
|
6647
6661
|
},
|
|
6648
6662
|
"indexes": [
|
|
6649
6663
|
{
|
|
6650
|
-
"name": "
|
|
6664
|
+
"name": "group_members_group_id_user_id_idx",
|
|
6651
6665
|
"columns": [
|
|
6652
|
-
"
|
|
6653
|
-
"
|
|
6666
|
+
"group_id",
|
|
6667
|
+
"user_id"
|
|
6654
6668
|
],
|
|
6655
6669
|
"unique": true
|
|
6656
6670
|
},
|
|
6657
6671
|
{
|
|
6658
|
-
"name": "
|
|
6672
|
+
"name": "group_members_slug_context_idx",
|
|
6659
6673
|
"columns": [
|
|
6660
|
-
"
|
|
6674
|
+
"slug",
|
|
6675
|
+
"context"
|
|
6661
6676
|
]
|
|
6662
6677
|
},
|
|
6663
6678
|
{
|
|
6664
|
-
"name": "
|
|
6679
|
+
"name": "group_members_created_at_idx",
|
|
6665
6680
|
"columns": [
|
|
6666
|
-
"
|
|
6681
|
+
"created_at"
|
|
6667
6682
|
]
|
|
6668
6683
|
},
|
|
6669
6684
|
{
|
|
@@ -7075,6 +7090,7 @@
|
|
|
7075
7090
|
"failed",
|
|
7076
7091
|
"succeeded",
|
|
7077
7092
|
"locked",
|
|
7093
|
+
"source-locked",
|
|
7078
7094
|
"managed"
|
|
7079
7095
|
]
|
|
7080
7096
|
},
|
|
@@ -7665,7 +7681,8 @@
|
|
|
7665
7681
|
"required": true,
|
|
7666
7682
|
"related": "Membership",
|
|
7667
7683
|
"_meta": {
|
|
7668
|
-
"required": true
|
|
7684
|
+
"required": true,
|
|
7685
|
+
"onDelete": "NO ACTION"
|
|
7669
7686
|
}
|
|
7670
7687
|
},
|
|
7671
7688
|
"permissionId": {
|
|
@@ -7673,7 +7690,8 @@
|
|
|
7673
7690
|
"required": true,
|
|
7674
7691
|
"related": "Permission",
|
|
7675
7692
|
"_meta": {
|
|
7676
|
-
"required": true
|
|
7693
|
+
"required": true,
|
|
7694
|
+
"onDelete": "NO ACTION"
|
|
7677
7695
|
}
|
|
7678
7696
|
},
|
|
7679
7697
|
"effect": {
|
|
@@ -7718,7 +7736,11 @@
|
|
|
7718
7736
|
"list",
|
|
7719
7737
|
"get"
|
|
7720
7738
|
]
|
|
7721
|
-
}
|
|
7739
|
+
},
|
|
7740
|
+
"conflictColumns": [
|
|
7741
|
+
"membership_id",
|
|
7742
|
+
"permission_id"
|
|
7743
|
+
]
|
|
7722
7744
|
},
|
|
7723
7745
|
"extends": "SmrtObject",
|
|
7724
7746
|
"exportName": "MembershipOverride",
|
|
@@ -7796,23 +7818,24 @@
|
|
|
7796
7818
|
},
|
|
7797
7819
|
"indexes": [
|
|
7798
7820
|
{
|
|
7799
|
-
"name": "
|
|
7821
|
+
"name": "membership_overrides_membership_id_permission_id_idx",
|
|
7800
7822
|
"columns": [
|
|
7801
|
-
"
|
|
7802
|
-
"
|
|
7823
|
+
"membership_id",
|
|
7824
|
+
"permission_id"
|
|
7803
7825
|
],
|
|
7804
7826
|
"unique": true
|
|
7805
7827
|
},
|
|
7806
7828
|
{
|
|
7807
|
-
"name": "
|
|
7829
|
+
"name": "membership_overrides_slug_context_idx",
|
|
7808
7830
|
"columns": [
|
|
7809
|
-
"
|
|
7831
|
+
"slug",
|
|
7832
|
+
"context"
|
|
7810
7833
|
]
|
|
7811
7834
|
},
|
|
7812
7835
|
{
|
|
7813
|
-
"name": "
|
|
7836
|
+
"name": "membership_overrides_created_at_idx",
|
|
7814
7837
|
"columns": [
|
|
7815
|
-
"
|
|
7838
|
+
"created_at"
|
|
7816
7839
|
]
|
|
7817
7840
|
},
|
|
7818
7841
|
{
|
|
@@ -11182,7 +11205,8 @@
|
|
|
11182
11205
|
"required": true,
|
|
11183
11206
|
"related": "Tenant",
|
|
11184
11207
|
"_meta": {
|
|
11185
|
-
"required": true
|
|
11208
|
+
"required": true,
|
|
11209
|
+
"onDelete": "NO ACTION"
|
|
11186
11210
|
}
|
|
11187
11211
|
},
|
|
11188
11212
|
"permissionId": {
|
|
@@ -11190,7 +11214,8 @@
|
|
|
11190
11214
|
"required": true,
|
|
11191
11215
|
"related": "Permission",
|
|
11192
11216
|
"_meta": {
|
|
11193
|
-
"required": true
|
|
11217
|
+
"required": true,
|
|
11218
|
+
"onDelete": "NO ACTION"
|
|
11194
11219
|
}
|
|
11195
11220
|
},
|
|
11196
11221
|
"effect": {
|
|
@@ -11254,8 +11279,7 @@
|
|
|
11254
11279
|
},
|
|
11255
11280
|
"conflictColumns": [
|
|
11256
11281
|
"tenant_id",
|
|
11257
|
-
"
|
|
11258
|
-
"context"
|
|
11282
|
+
"permission_id"
|
|
11259
11283
|
]
|
|
11260
11284
|
},
|
|
11261
11285
|
"extends": "SmrtObject",
|
|
@@ -11334,14 +11358,20 @@
|
|
|
11334
11358
|
},
|
|
11335
11359
|
"indexes": [
|
|
11336
11360
|
{
|
|
11337
|
-
"name": "
|
|
11361
|
+
"name": "tenant_permission_overrides_tenant_id_permission_id_idx",
|
|
11338
11362
|
"columns": [
|
|
11339
11363
|
"tenant_id",
|
|
11340
|
-
"
|
|
11341
|
-
"context"
|
|
11364
|
+
"permission_id"
|
|
11342
11365
|
],
|
|
11343
11366
|
"unique": true
|
|
11344
11367
|
},
|
|
11368
|
+
{
|
|
11369
|
+
"name": "tenant_permission_overrides_slug_context_idx",
|
|
11370
|
+
"columns": [
|
|
11371
|
+
"slug",
|
|
11372
|
+
"context"
|
|
11373
|
+
]
|
|
11374
|
+
},
|
|
11345
11375
|
{
|
|
11346
11376
|
"name": "tenant_permission_overrides_created_at_idx",
|
|
11347
11377
|
"columns": [
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
2
|
+
import { type NaturalKeyDedupOptions, type NaturalKeyDedupResult } from './natural-key-dedup.js';
|
|
3
|
+
/** Options for the explicit, maintenance-window authority-pair migration. */
|
|
4
|
+
export type DeduplicateAuthorityPairsOptions = NaturalKeyDedupOptions;
|
|
5
|
+
/** Per-table result of {@link deduplicateAuthorityPairs}. */
|
|
6
|
+
export interface DeduplicateAuthorityPairsResult {
|
|
7
|
+
membershipOverrides: NaturalKeyDedupResult;
|
|
8
|
+
tenantPermissionOverrides: NaturalKeyDedupResult;
|
|
9
|
+
groupMembers: NaturalKeyDedupResult;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Collapse duplicate `MembershipOverride`, `TenantPermissionOverride` and
|
|
13
|
+
* `GroupMember` rows to one per natural-key pair and install the unique
|
|
14
|
+
* indexes their models now declare (#3375). Run BEFORE ordinary schema
|
|
15
|
+
* migration, with every writer stopped: adding the indexes directly fails
|
|
16
|
+
* while duplicates exist, and older application versions do not write
|
|
17
|
+
* against them safely.
|
|
18
|
+
*
|
|
19
|
+
* Override pairs keep the row whose effect the resolver already applies
|
|
20
|
+
* (DENY, then GRANT, then INHERIT), so the effective authority of every pair
|
|
21
|
+
* is unchanged; ties, and group memberships, keep the earliest `created_at`
|
|
22
|
+
* (lowest `id` breaks ties; null timestamps sort last). Survivors are
|
|
23
|
+
* unchanged. All three tables commit together; failure leaves them intact.
|
|
24
|
+
* Re-running is safe.
|
|
25
|
+
*/
|
|
26
|
+
export declare function deduplicateAuthorityPairs(db: DatabaseInterface, options?: DeduplicateAuthorityPairsOptions): Promise<DeduplicateAuthorityPairsResult>;
|
|
27
|
+
//# sourceMappingURL=deduplicateAuthorityPairs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deduplicateAuthorityPairs.d.ts","sourceRoot":"","sources":["../../src/migrations/deduplicateAuthorityPairs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE3B,MAAM,wBAAwB,CAAC;AAEhC,6EAA6E;AAC7E,MAAM,MAAM,gCAAgC,GAAG,sBAAsB,CAAC;AAEtE,6DAA6D;AAC7D,MAAM,WAAW,+BAA+B;IAC9C,mBAAmB,EAAE,qBAAqB,CAAC;IAC3C,yBAAyB,EAAE,qBAAqB,CAAC;IACjD,YAAY,EAAE,qBAAqB,CAAC;CACrC;AAgCD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,iBAAiB,EACrB,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,+BAA+B,CAAC,CAS1C"}
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
2
|
+
import { type NaturalKeyDedupOptions, type NaturalKeyDedupResult } from './natural-key-dedup.js';
|
|
2
3
|
/** Options for the explicit, maintenance-window grant migration. */
|
|
3
|
-
export
|
|
4
|
-
/** Inspect the duplicate count without changing rows or indexes. */
|
|
5
|
-
dryRun?: boolean;
|
|
6
|
-
/** Confirm all application writers and seeders are stopped. */
|
|
7
|
-
maintenanceConfirmed?: boolean;
|
|
8
|
-
}
|
|
4
|
+
export type DeduplicateRolePermissionsOptions = NaturalKeyDedupOptions;
|
|
9
5
|
/** Result of the grant migration; removed is zero for a dry run. */
|
|
10
|
-
export
|
|
11
|
-
duplicates: number;
|
|
12
|
-
removed: number;
|
|
13
|
-
}
|
|
6
|
+
export type DeduplicateRolePermissionsResult = NaturalKeyDedupResult;
|
|
14
7
|
/**
|
|
15
8
|
* Keep the oldest grant for each role/permission pair and install its unique
|
|
16
9
|
* index. Run BEFORE ordinary schema migration, with every writer stopped;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deduplicateRolePermissions.d.ts","sourceRoot":"","sources":["../../src/migrations/deduplicateRolePermissions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deduplicateRolePermissions.d.ts","sourceRoot":"","sources":["../../src/migrations/deduplicateRolePermissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,wBAAwB,CAAC;AAEhC,oEAAoE;AACpE,MAAM,MAAM,iCAAiC,GAAG,sBAAsB,CAAC;AAEvE,oEAAoE;AACpE,MAAM,MAAM,gCAAgC,GAAG,qBAAqB,CAAC;AAErE;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,iBAAiB,EACrB,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,gCAAgC,CAAC,CAc3C"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
2
|
+
/** Options shared by the maintenance-window natural-key migrations. */
|
|
3
|
+
export interface NaturalKeyDedupOptions {
|
|
4
|
+
/** Inspect the duplicate count without changing rows or indexes. */
|
|
5
|
+
dryRun?: boolean;
|
|
6
|
+
/** Confirm all application writers and seeders are stopped. */
|
|
7
|
+
maintenanceConfirmed?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/** Per-table result; removed is zero for a dry run. */
|
|
10
|
+
export interface NaturalKeyDedupResult {
|
|
11
|
+
duplicates: number;
|
|
12
|
+
removed: number;
|
|
13
|
+
}
|
|
14
|
+
/** One table whose rows must be unique on a column pair. */
|
|
15
|
+
export interface NaturalKeyDedupTarget {
|
|
16
|
+
table: string;
|
|
17
|
+
columns: readonly [string, string];
|
|
18
|
+
/** Unique index the generated schema declares for the pair. */
|
|
19
|
+
index: string;
|
|
20
|
+
/**
|
|
21
|
+
* Leading ORDER BY terms that choose the survivor before the oldest-row
|
|
22
|
+
* rule, e.g. the effect the resolver already applies for the pair.
|
|
23
|
+
*/
|
|
24
|
+
survivorOrder?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Remove natural-key duplicates and install each target's unique index in one
|
|
28
|
+
* transaction, so failure leaves every table as it was. Run BEFORE ordinary
|
|
29
|
+
* schema migration with every writer stopped. Re-running is safe.
|
|
30
|
+
*/
|
|
31
|
+
export declare function deduplicateNaturalKeys(db: DatabaseInterface, targets: readonly NaturalKeyDedupTarget[], options: NaturalKeyDedupOptions, label: string): Promise<NaturalKeyDedupResult[]>;
|
|
32
|
+
//# sourceMappingURL=natural-key-dedup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"natural-key-dedup.d.ts","sourceRoot":"","sources":["../../src/migrations/natural-key-dedup.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,uEAAuE;AACvE,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,uDAAuD;AACvD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAcD;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,iBAAiB,EACrB,OAAO,EAAE,SAAS,qBAAqB,EAAE,EACzC,OAAO,EAAE,sBAAsB,EAC/B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAyDlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupMember.d.ts","sourceRoot":"","sources":["../../src/models/GroupMember.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,
|
|
1
|
+
{"version":3,"file":"GroupMember.d.ts","sourceRoot":"","sources":["../../src/models/GroupMember.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAaa,WAAY,SAAQ,UAAU;IACzC;;OAEG;IAEH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IAEH,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEJ,OAAO,GAAE,kBAAuB;CAK7C"}
|
|
@@ -19,6 +19,11 @@ export type LoginAuditOutcome =
|
|
|
19
19
|
| 'succeeded'
|
|
20
20
|
/** A failure exhausted the budget and the key is now locked out. */
|
|
21
21
|
| 'locked'
|
|
22
|
+
/**
|
|
23
|
+
* A failure started a SOURCE lockout (#3531). Carries the source hash only,
|
|
24
|
+
* never a subject; rate limited per source.
|
|
25
|
+
*/
|
|
26
|
+
| 'source-locked'
|
|
22
27
|
/** A credential was set, reset, or cleared (administrative). */
|
|
23
28
|
| 'managed';
|
|
24
29
|
export declare class UsersLoginAuditEvent extends SmrtObject {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginAuditEvent.d.ts","sourceRoot":"","sources":["../../src/models/LoginAuditEvent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAS,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAEnE,0CAA0C;AAC1C,MAAM,MAAM,iBAAiB;AAC3B,0EAA0E;AACxE,QAAQ;AACV,wDAAwD;GACtD,QAAQ;AACV,yCAAyC;GACvC,WAAW;AACb,oEAAoE;GAClE,QAAQ;AACV,gEAAgE;GAC9D,SAAS,CAAC;AAEd,qBASa,oBAAqB,SAAQ,UAAU;IAClD,2EAA2E;IAE3E,IAAI,SAAM;IAGV,OAAO,EAAE,iBAAiB,CAAY;IAEtC,mEAAmE;IAEnE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAQ;IAErC,gFAAgF;IAEhF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,sEAAsE;IAEtE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC;;;;OAIG;IAEH,UAAU,OAAc;IAExB;;;;OAIG;IAEH,QAAQ,SAAQ;IAEhB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAWtC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAGlD"}
|
|
1
|
+
{"version":3,"file":"LoginAuditEvent.d.ts","sourceRoot":"","sources":["../../src/models/LoginAuditEvent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAS,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAEnE,0CAA0C;AAC1C,MAAM,MAAM,iBAAiB;AAC3B,0EAA0E;AACxE,QAAQ;AACV,wDAAwD;GACtD,QAAQ;AACV,yCAAyC;GACvC,WAAW;AACb,oEAAoE;GAClE,QAAQ;AACV;;;GAGG;GACD,eAAe;AACjB,gEAAgE;GAC9D,SAAS,CAAC;AAEd,qBASa,oBAAqB,SAAQ,UAAU;IAClD,2EAA2E;IAE3E,IAAI,SAAM;IAGV,OAAO,EAAE,iBAAiB,CAAY;IAEtC,mEAAmE;IAEnE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAQ;IAErC,gFAAgF;IAEhF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,sEAAsE;IAEtE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC;;;;OAIG;IAEH,UAAU,OAAc;IAExB;;;;OAIG;IAEH,QAAQ,SAAQ;IAEhB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAWtC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAGlD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MembershipOverride.d.ts","sourceRoot":"","sources":["../../src/models/MembershipOverride.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,iBAAiB;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,
|
|
1
|
+
{"version":3,"file":"MembershipOverride.d.ts","sourceRoot":"","sources":["../../src/models/MembershipOverride.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,iBAAiB;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAaa,kBAAmB,SAAQ,UAAU;IAChD;;OAEG;IAEH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IAEH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IAEH,MAAM,EAAE,cAAc,CAAwB;gBAElC,OAAO,GAAE,yBAA8B;IASnD;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,MAAM,IAAI,OAAO;CAGlB"}
|
package/dist/models/Session.d.ts
CHANGED
|
@@ -43,6 +43,15 @@ export declare const SESSION_DATA_KEYS: {
|
|
|
43
43
|
readonly absoluteExpiresAt: "absoluteExpiresAt";
|
|
44
44
|
/** Sliding idle timeout in seconds, applied on every recorded activity. */
|
|
45
45
|
readonly idleSeconds: "idleSeconds";
|
|
46
|
+
/**
|
|
47
|
+
* ISO timestamp of the out-of-band proof (a recovery link, an operator-
|
|
48
|
+
* issued code) a host verified before minting this session (#3905). Set
|
|
49
|
+
* only by the host's recovery flow at mint; it is what
|
|
50
|
+
* `PasswordCredentialService.replaceForgottenPassword` measures freshness
|
|
51
|
+
* from, and it survives tenant-switch rotation (unlike the row's
|
|
52
|
+
* `created_at`).
|
|
53
|
+
*/
|
|
54
|
+
readonly outOfBandProofAt: "outOfBandProofAt";
|
|
46
55
|
};
|
|
47
56
|
/**
|
|
48
57
|
* Expiry for a session minted or extended now: `ttlSeconds` ahead, bounded by
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Session.d.ts","sourceRoot":"","sources":["../../src/models/Session.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mEAAmE;IACnE,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,cAAc,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,YAAY,GACZ,UAAU,GACV,QAAQ,GACR,KAAK,GACL,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAmB,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;IAC5B,qFAAqF;;IAErF,8EAA8E;;IAE9E,2EAA2E;;
|
|
1
|
+
{"version":3,"file":"Session.d.ts","sourceRoot":"","sources":["../../src/models/Session.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TenantPermissionOverride.d.ts","sourceRoot":"","sources":["../../src/models/TenantPermissionOverride.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,+BAAgC,SAAQ,iBAAiB;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,
|
|
1
|
+
{"version":3,"file":"TenantPermissionOverride.d.ts","sourceRoot":"","sources":["../../src/models/TenantPermissionOverride.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EACV,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,+BAAgC,SAAQ,iBAAiB;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAaa,wBAAyB,SAAQ,UAAU;IACtD;;OAEG;IAEH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IAEH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IAEH,MAAM,EAAE,sBAAsB,CAAkC;gBAEpD,OAAO,GAAE,+BAAoC;IAQzD;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,iBAAiB,IAAI,OAAO;CAG7B"}
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
* the client submitted — an email key or user id, never a resolved account)
|
|
22
22
|
* and the **source** (client IP, or the device/station the attempt came
|
|
23
23
|
* from). Either one being exhausted refuses the attempt. Both are stored as
|
|
24
|
-
* hashes.
|
|
24
|
+
* hashes. Each budget can be sized on its own (`subject`, `source`), and the
|
|
25
|
+
* source budget can be turned off (`source: false`) where no trustworthy
|
|
26
|
+
* client address exists (#3531).
|
|
25
27
|
*
|
|
26
28
|
* ## Non-enumeration
|
|
27
29
|
*
|
|
@@ -49,7 +51,10 @@
|
|
|
49
51
|
*
|
|
50
52
|
* Every decision is reported to a {@link LoginAuditSink}. The default sink
|
|
51
53
|
* persists {@link UsersLoginAuditEvent} rows; pass `audit: false` to disable
|
|
52
|
-
* or supply a sink that forwards to the host's own log.
|
|
54
|
+
* or supply a sink that forwards to the host's own log. When a failure starts
|
|
55
|
+
* a SOURCE lockout the limiter also reports one `source-locked` entry that
|
|
56
|
+
* carries the source hash but no subject (so it never names the accounts that
|
|
57
|
+
* were tried), at most once per source per `sourceLockoutAuditSeconds`.
|
|
53
58
|
*
|
|
54
59
|
* @packageDocumentation
|
|
55
60
|
*/
|
|
@@ -66,6 +71,8 @@ export declare const DEFAULT_LOGIN_LOCKOUT_BASE_SECONDS = 60;
|
|
|
66
71
|
export declare const DEFAULT_LOGIN_LOCKOUT_FACTOR = 2;
|
|
67
72
|
/** Default lockout ceiling (1 hour). */
|
|
68
73
|
export declare const DEFAULT_LOGIN_LOCKOUT_MAX_SECONDS: number;
|
|
74
|
+
/** Default minimum spacing of `source-locked` audit entries per source (5 minutes). */
|
|
75
|
+
export declare const DEFAULT_SOURCE_LOCKOUT_AUDIT_SECONDS: number;
|
|
69
76
|
export interface LoginLockoutOptions {
|
|
70
77
|
baseSeconds?: number;
|
|
71
78
|
factor?: number;
|
|
@@ -81,6 +88,18 @@ export interface LoginAuditEntry {
|
|
|
81
88
|
occurredAt: Date;
|
|
82
89
|
metadata?: Record<string, unknown>;
|
|
83
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* One budget's sizing (#3531). Every field falls back to the limiter's
|
|
93
|
+
* top-level option of the same meaning.
|
|
94
|
+
*/
|
|
95
|
+
export interface LoginBudgetOptions {
|
|
96
|
+
/** Failed attempts allowed per window (top-level `maxAttempts`). */
|
|
97
|
+
maxFailures?: number;
|
|
98
|
+
/** Sliding window in seconds (top-level `windowSeconds`). */
|
|
99
|
+
windowSeconds?: number;
|
|
100
|
+
/** Lockout once the budget is exhausted; `false` keeps only the window. */
|
|
101
|
+
lockout?: LoginLockoutOptions | false;
|
|
102
|
+
}
|
|
84
103
|
/** Where sign-in decisions are reported. Must not throw into the sign-in path. */
|
|
85
104
|
export interface LoginAuditSink {
|
|
86
105
|
record(entry: LoginAuditEntry): Promise<void>;
|
|
@@ -96,9 +115,30 @@ export interface LoginAttemptLimiterOptions extends SmrtClassOptions {
|
|
|
96
115
|
* terminal-approve behaviour).
|
|
97
116
|
*/
|
|
98
117
|
lockout?: LoginLockoutOptions | false;
|
|
118
|
+
/**
|
|
119
|
+
* Per-account budget (#3531). Omitted fields use the top-level options.
|
|
120
|
+
*/
|
|
121
|
+
subject?: LoginBudgetOptions;
|
|
122
|
+
/**
|
|
123
|
+
* Per-address (or per-device) budget (#3531). Omitted fields use the
|
|
124
|
+
* top-level options. `false` ignores the source key entirely — for a
|
|
125
|
+
* deployment that cannot see a trustworthy client address, where every
|
|
126
|
+
* browser would otherwise share one budget and a handful of failures from
|
|
127
|
+
* anyone would lock everyone out. A reservation then needs a subject.
|
|
128
|
+
* This applies to every credential kind using this instance, so a host
|
|
129
|
+
* whose PIN sign-ins share it should prefer a larger source budget (or a
|
|
130
|
+
* separate limiter for passwords) over disabling it.
|
|
131
|
+
*/
|
|
132
|
+
source?: LoginBudgetOptions | false;
|
|
133
|
+
/**
|
|
134
|
+
* Minimum spacing, per source, of the `source-locked` audit entry reported
|
|
135
|
+
* when a failure starts a source lockout. Defaults to
|
|
136
|
+
* {@link DEFAULT_SOURCE_LOCKOUT_AUDIT_SECONDS}. Tracked per instance.
|
|
137
|
+
*/
|
|
138
|
+
sourceLockoutAuditSeconds?: number;
|
|
99
139
|
/**
|
|
100
140
|
* Time since a key's last failure after which its streak is forgiven. Defaults to
|
|
101
|
-
* twice the larger of the window and
|
|
141
|
+
* twice the larger of the budget's window and lockout ceiling.
|
|
102
142
|
*/
|
|
103
143
|
streakResetSeconds?: number;
|
|
104
144
|
/**
|
|
@@ -188,22 +228,26 @@ export declare class DurableLoginAuditSink implements LoginAuditSink {
|
|
|
188
228
|
}
|
|
189
229
|
export declare class LoginAttemptLimiter {
|
|
190
230
|
private readonly options;
|
|
191
|
-
private readonly
|
|
192
|
-
private readonly windowMs;
|
|
193
|
-
private readonly lockout;
|
|
194
|
-
private readonly streakResetMs;
|
|
231
|
+
private readonly budgets;
|
|
195
232
|
private readonly sourceStreakDecayMs;
|
|
233
|
+
private readonly sourceLockoutAuditMs;
|
|
234
|
+
/** Source hash → earliest time its next `source-locked` entry may be reported. */
|
|
235
|
+
private readonly sourceLockoutAudited;
|
|
196
236
|
private attempts;
|
|
197
237
|
private audit;
|
|
198
238
|
constructor(options: LoginAttemptLimiterOptions);
|
|
239
|
+
/** False when this limiter was configured with `source: false`. */
|
|
240
|
+
get limitsSource(): boolean;
|
|
199
241
|
static create(options: LoginAttemptLimiterOptions): Promise<LoginAttemptLimiter>;
|
|
200
242
|
initialize(): Promise<void>;
|
|
201
|
-
/** How long a row this limiter writes must outlive the retention sweep. */
|
|
202
|
-
private get retainMs();
|
|
203
243
|
/** Stable, peppered hash for a key. Exposed so hosts can correlate audit rows. */
|
|
204
244
|
hashKey(scope: LoginAttemptScope, raw: string): string;
|
|
205
|
-
/**
|
|
206
|
-
|
|
245
|
+
/**
|
|
246
|
+
* Lockout length for the n-th consecutive exhausted budget (0-based) of the
|
|
247
|
+
* given scope's budget (the subject's by default).
|
|
248
|
+
*/
|
|
249
|
+
lockoutMsFor(exhaustedBudgets: number, scope?: LoginAttemptScope): number;
|
|
250
|
+
private budgetFor;
|
|
207
251
|
/**
|
|
208
252
|
* Reserve one attempt against every key supplied. Subject is reserved
|
|
209
253
|
* first; if the source then refuses, the subject reservation is handed
|
|
@@ -222,6 +266,13 @@ export declare class LoginAttemptLimiter {
|
|
|
222
266
|
dryRun?: boolean;
|
|
223
267
|
}): Promise<number>;
|
|
224
268
|
private releaseAll;
|
|
269
|
+
/**
|
|
270
|
+
* Report that a source lockout started, without the subject or the caller's
|
|
271
|
+
* metadata, so the entry attributes the outage to the address or device but
|
|
272
|
+
* never names an attempted account. Rate limited per source, in memory, so
|
|
273
|
+
* a sustained attack yields a bounded number of entries per instance.
|
|
274
|
+
*/
|
|
275
|
+
private reportSourceLockout;
|
|
225
276
|
private report;
|
|
226
277
|
}
|
|
227
278
|
//# sourceMappingURL=LoginAttemptLimiter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginAttemptLimiter.d.ts","sourceRoot":"","sources":["../../src/services/LoginAttemptLimiter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"LoginAttemptLimiter.d.ts","sourceRoot":"","sources":["../../src/services/LoginAttemptLimiter.ts"],"names":[],"mappings":"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"}
|