@aventara/access 0.0.0-stage → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/CHANGELOG.md +877 -0
  2. package/LICENSE +91 -0
  3. package/LICENSE-ADDITIONAL-PERMISSION.md +9 -0
  4. package/README.md +2536 -2
  5. package/dist/access/access-options.d.ts +74 -0
  6. package/dist/access/access-options.js +5 -0
  7. package/dist/access/access.error.d.ts +35 -0
  8. package/dist/access/access.error.js +11 -0
  9. package/dist/access/access.factory.d.ts +275 -0
  10. package/dist/access/access.factory.js +440 -0
  11. package/dist/access/better-auth.hardening.d.ts +120 -0
  12. package/dist/access/better-auth.hardening.js +420 -0
  13. package/dist/access/better-auth.loader.d.ts +67 -0
  14. package/dist/access/better-auth.loader.js +65 -0
  15. package/dist/access/better-auth.range.d.ts +9 -0
  16. package/dist/access/better-auth.range.js +28 -0
  17. package/dist/access/better-auth.require.d.ts +90 -0
  18. package/dist/access/better-auth.require.js +6 -0
  19. package/dist/access/better-auth.require.node.d.ts +7 -0
  20. package/dist/access/better-auth.require.node.js +52 -0
  21. package/dist/access/claims.mapper.d.ts +79 -0
  22. package/dist/access/claims.mapper.js +152 -0
  23. package/dist/access/key-set.cache.d.ts +10 -0
  24. package/dist/access/key-set.cache.js +63 -0
  25. package/dist/access/policies-block.checker.d.ts +64 -0
  26. package/dist/access/policies-block.checker.js +138 -0
  27. package/dist/access/principal.subject.d.ts +22 -0
  28. package/dist/access/principal.subject.js +89 -0
  29. package/dist/access/profile.policy.d.ts +74 -0
  30. package/dist/access/profile.policy.js +110 -0
  31. package/dist/access/request.state.d.ts +89 -0
  32. package/dist/access/request.state.js +266 -0
  33. package/dist/access/session.hooks.d.ts +114 -0
  34. package/dist/access/session.hooks.js +258 -0
  35. package/dist/access/token.verifier.d.ts +35 -0
  36. package/dist/access/token.verifier.js +69 -0
  37. package/dist/access-schema.d.ts +48 -0
  38. package/dist/access-schema.js +5 -0
  39. package/dist/access-warning.emitter.d.ts +4 -0
  40. package/dist/access-warning.emitter.js +24 -0
  41. package/dist/access.builder.d.ts +340 -0
  42. package/dist/access.builder.js +75 -0
  43. package/dist/access.engine.d.ts +155 -0
  44. package/dist/access.engine.js +477 -0
  45. package/dist/audit/audit-event.d.ts +135 -0
  46. package/dist/audit/audit-event.js +8 -0
  47. package/dist/audit/audit.log.d.ts +122 -0
  48. package/dist/audit/audit.log.js +345 -0
  49. package/dist/audit/audit.schema.d.ts +143 -0
  50. package/dist/audit/audit.schema.js +50 -0
  51. package/dist/auth/index.d.ts +12 -0
  52. package/dist/auth/index.js +2 -0
  53. package/dist/aventara-where.translator.d.ts +19 -0
  54. package/dist/aventara-where.translator.js +87 -0
  55. package/dist/beacon/beacon.check.d.ts +59 -0
  56. package/dist/beacon/beacon.check.js +128 -0
  57. package/dist/beacon/beacon.schema.d.ts +41 -0
  58. package/dist/beacon/beacon.schema.js +48 -0
  59. package/dist/beacon/beacon.store.d.ts +29 -0
  60. package/dist/beacon/beacon.store.js +78 -0
  61. package/dist/better-auth/access.client-plugin.d.ts +75 -0
  62. package/dist/better-auth/access.client-plugin.js +133 -0
  63. package/dist/better-auth/access.plugin.d.ts +164 -0
  64. package/dist/better-auth/access.plugin.js +348 -0
  65. package/dist/better-auth/access.provider.d.ts +80 -0
  66. package/dist/better-auth/access.provider.js +100 -0
  67. package/dist/better-auth/index.d.ts +7 -0
  68. package/dist/better-auth/index.js +4 -0
  69. package/dist/better-auth/organization.bridge.d.ts +66 -0
  70. package/dist/better-auth/organization.bridge.js +144 -0
  71. package/dist/canonical-json.writer.d.ts +12 -0
  72. package/dist/canonical-json.writer.js +30 -0
  73. package/dist/cli/avaccess.bin.d.ts +2 -0
  74. package/dist/cli/avaccess.bin.js +26 -0
  75. package/dist/cli/avaccess.program.d.ts +15 -0
  76. package/dist/cli/avaccess.program.js +166 -0
  77. package/dist/cli/beacon-pins.file.d.ts +14 -0
  78. package/dist/cli/beacon-pins.file.js +62 -0
  79. package/dist/cli/beacon.loader.d.ts +20 -0
  80. package/dist/cli/beacon.loader.js +71 -0
  81. package/dist/cli/cli.context.d.ts +49 -0
  82. package/dist/cli/cli.context.js +66 -0
  83. package/dist/cli/diff.command.d.ts +2 -0
  84. package/dist/cli/diff.command.js +66 -0
  85. package/dist/cli/generate.command.d.ts +2 -0
  86. package/dist/cli/generate.command.js +82 -0
  87. package/dist/cli/keys.command.d.ts +2 -0
  88. package/dist/cli/keys.command.js +96 -0
  89. package/dist/cli/lock.file.d.ts +31 -0
  90. package/dist/cli/lock.file.js +181 -0
  91. package/dist/cli/module.loader.d.ts +13 -0
  92. package/dist/cli/module.loader.js +63 -0
  93. package/dist/cli/policies.diff.d.ts +16 -0
  94. package/dist/cli/policies.diff.js +101 -0
  95. package/dist/cli/pull.command.d.ts +2 -0
  96. package/dist/cli/pull.command.js +234 -0
  97. package/dist/cli/push.command.d.ts +2 -0
  98. package/dist/cli/push.command.js +59 -0
  99. package/dist/cli/registry.client.d.ts +63 -0
  100. package/dist/cli/registry.client.js +287 -0
  101. package/dist/cli/schema.command.d.ts +2 -0
  102. package/dist/cli/schema.command.js +60 -0
  103. package/dist/cli/serve.command.d.ts +6 -0
  104. package/dist/cli/serve.command.js +200 -0
  105. package/dist/cli/status.command.d.ts +2 -0
  106. package/dist/cli/status.command.js +31 -0
  107. package/dist/cli/translator.flag.d.ts +6 -0
  108. package/dist/cli/translator.flag.js +24 -0
  109. package/dist/cli/verify.command.d.ts +2 -0
  110. package/dist/cli/verify.command.js +40 -0
  111. package/dist/client/access-client.factory.d.ts +92 -0
  112. package/dist/client/access-client.factory.js +269 -0
  113. package/dist/client/access-verbs.schema.d.ts +66 -0
  114. package/dist/client/access-verbs.schema.js +159 -0
  115. package/dist/client/verb-rate.limiter.d.ts +116 -0
  116. package/dist/client/verb-rate.limiter.js +358 -0
  117. package/dist/foreign/foreign-facts.d.ts +30 -0
  118. package/dist/foreign/foreign-facts.js +75 -0
  119. package/dist/foreign/foreign.merger.d.ts +10 -0
  120. package/dist/foreign/foreign.merger.js +52 -0
  121. package/dist/foreign-references.check.d.ts +6 -0
  122. package/dist/foreign-references.check.js +131 -0
  123. package/dist/generator/client.emitter.d.ts +28 -0
  124. package/dist/generator/client.emitter.js +411 -0
  125. package/dist/generator/copied-modules.reader.d.ts +14 -0
  126. package/dist/generator/copied-modules.reader.js +80 -0
  127. package/dist/generator/namespace.facts.d.ts +28 -0
  128. package/dist/generator/namespace.facts.js +32 -0
  129. package/dist/generator/orm.translator.d.ts +48 -0
  130. package/dist/generator/orm.translator.js +29 -0
  131. package/dist/generator/prisma7/prisma-schema.reader.d.ts +9 -0
  132. package/dist/generator/prisma7/prisma-schema.reader.js +394 -0
  133. package/dist/generator/prisma7/prisma-where.translator.d.ts +73 -0
  134. package/dist/generator/prisma7/prisma-where.translator.js +138 -0
  135. package/dist/generator/prisma7/prisma7.translator.d.ts +2 -0
  136. package/dist/generator/prisma7/prisma7.translator.js +87 -0
  137. package/dist/generator/schema.emitter.d.ts +14 -0
  138. package/dist/generator/schema.emitter.js +23 -0
  139. package/dist/generator/tsconfig.reader.d.ts +44 -0
  140. package/dist/generator/tsconfig.reader.js +110 -0
  141. package/dist/generator/typescript-literal.writer.d.ts +5 -0
  142. package/dist/generator/typescript-literal.writer.js +42 -0
  143. package/dist/guardrails/guardrails-contract.d.ts +45 -0
  144. package/dist/guardrails/guardrails-contract.js +12 -0
  145. package/dist/guardrails/guardrails.builder.d.ts +48 -0
  146. package/dist/guardrails/guardrails.builder.js +32 -0
  147. package/dist/guardrails/guardrails.compiler.d.ts +10 -0
  148. package/dist/guardrails/guardrails.compiler.js +254 -0
  149. package/dist/guardrails/guardrails.composer.d.ts +7 -0
  150. package/dist/guardrails/guardrails.composer.js +95 -0
  151. package/dist/guardrails/guardrails.hash.d.ts +10 -0
  152. package/dist/guardrails/guardrails.hash.js +38 -0
  153. package/dist/index.d.ts +16 -0
  154. package/dist/index.js +6 -0
  155. package/dist/kiosk/kiosk-verbs.schema.d.ts +19 -0
  156. package/dist/kiosk/kiosk-verbs.schema.js +61 -0
  157. package/dist/kiosk/kiosk.plugin.d.ts +217 -0
  158. package/dist/kiosk/kiosk.plugin.js +877 -0
  159. package/dist/kiosk/kiosk.schema.d.ts +176 -0
  160. package/dist/kiosk/kiosk.schema.js +101 -0
  161. package/dist/kiosk/kiosk.store.d.ts +171 -0
  162. package/dist/kiosk/kiosk.store.js +478 -0
  163. package/dist/kiosk/lan-range.policy.d.ts +31 -0
  164. package/dist/kiosk/lan-range.policy.js +113 -0
  165. package/dist/kiosk/pin.policy.d.ts +9 -0
  166. package/dist/kiosk/pin.policy.js +143 -0
  167. package/dist/kiosk/session-use.marker.d.ts +4 -0
  168. package/dist/kiosk/session-use.marker.js +16 -0
  169. package/dist/lock/lock-contract.d.ts +38 -0
  170. package/dist/lock/lock-contract.js +67 -0
  171. package/dist/lock/lock.verifier.d.ts +27 -0
  172. package/dist/lock/lock.verifier.js +62 -0
  173. package/dist/mcp/agent-scope.gate.d.ts +13 -0
  174. package/dist/mcp/agent-scope.gate.js +75 -0
  175. package/dist/mcp/agent.grant.d.ts +40 -0
  176. package/dist/mcp/agent.grant.js +92 -0
  177. package/dist/mcp/mcp-options.d.ts +60 -0
  178. package/dist/mcp/mcp-options.js +72 -0
  179. package/dist/oauth/access-token.verifier.d.ts +66 -0
  180. package/dist/oauth/access-token.verifier.js +201 -0
  181. package/dist/oauth/oauth-provider.hardening.d.ts +62 -0
  182. package/dist/oauth/oauth-provider.hardening.js +261 -0
  183. package/dist/passwords/argon2id.hasher.d.ts +97 -0
  184. package/dist/passwords/argon2id.hasher.js +256 -0
  185. package/dist/passwords/node-rs-argon2.adapter.d.ts +25 -0
  186. package/dist/passwords/node-rs-argon2.adapter.js +42 -0
  187. package/dist/passwords/passwords.options.d.ts +79 -0
  188. package/dist/passwords/passwords.options.js +212 -0
  189. package/dist/policies-contract.d.ts +219 -0
  190. package/dist/policies-contract.js +8 -0
  191. package/dist/policies.compiler.d.ts +38 -0
  192. package/dist/policies.compiler.js +1433 -0
  193. package/dist/policies.decider.d.ts +103 -0
  194. package/dist/policies.decider.js +390 -0
  195. package/dist/policies.hash.d.ts +10 -0
  196. package/dist/policies.hash.js +54 -0
  197. package/dist/predicate.evaluator.d.ts +62 -0
  198. package/dist/predicate.evaluator.js +378 -0
  199. package/dist/random-secret.generator.d.ts +2 -0
  200. package/dist/random-secret.generator.js +15 -0
  201. package/dist/read-governed-unique.check.d.ts +3 -0
  202. package/dist/read-governed-unique.check.js +21 -0
  203. package/dist/reference-reads.check.d.ts +16 -0
  204. package/dist/reference-reads.check.js +158 -0
  205. package/dist/registry/access.registry.d.ts +173 -0
  206. package/dist/registry/access.registry.js +865 -0
  207. package/dist/registry/beacon.ledger.d.ts +30 -0
  208. package/dist/registry/beacon.ledger.js +93 -0
  209. package/dist/registry/ownership.check.d.ts +54 -0
  210. package/dist/registry/ownership.check.js +221 -0
  211. package/dist/registry/registry.endpoints.d.ts +50 -0
  212. package/dist/registry/registry.endpoints.js +193 -0
  213. package/dist/registry/registry.key.d.ts +7 -0
  214. package/dist/registry/registry.key.js +13 -0
  215. package/dist/registry/registry.options.d.ts +13 -0
  216. package/dist/registry/registry.options.js +28 -0
  217. package/dist/registry/registry.refusal.d.ts +6 -0
  218. package/dist/registry/registry.refusal.js +11 -0
  219. package/dist/registry/registry.schema.d.ts +238 -0
  220. package/dist/registry/registry.schema.js +127 -0
  221. package/dist/resources/auth-tables.catalog.d.ts +96 -0
  222. package/dist/resources/auth-tables.catalog.js +110 -0
  223. package/dist/resources/auth-tables.guard.d.ts +106 -0
  224. package/dist/resources/auth-tables.guard.js +462 -0
  225. package/dist/scope.resolver.d.ts +144 -0
  226. package/dist/scope.resolver.js +529 -0
  227. package/dist/sha256.digest.d.ts +2 -0
  228. package/dist/sha256.digest.js +81 -0
  229. package/dist/standalone/access.server.d.ts +41 -0
  230. package/dist/standalone/access.server.js +301 -0
  231. package/dist/standalone/index.d.ts +1 -0
  232. package/dist/standalone/index.js +1 -0
  233. package/package.json +102 -3
  234. package/skill/SKILL.md +170 -0
  235. package/skill/reference/callers.md +99 -0
  236. package/skill/reference/errors.md +89 -0
  237. package/skill/reference/recipes.md +281 -0
  238. package/skill/reference/rules.md +153 -0
  239. package/skill/reference/setup.md +334 -0
  240. package/src/aventara-where.translator.ts +116 -0
  241. package/src/beacon/beacon.check.ts +204 -0
  242. package/src/canonical-json.writer.ts +51 -0
  243. package/src/generator/prisma7/prisma-where.translator.ts +243 -0
  244. package/src/policies-contract.ts +215 -0
  245. package/src/policies.decider.ts +662 -0
  246. package/src/predicate.evaluator.ts +574 -0
  247. package/src/scope.resolver.ts +819 -0
  248. package/src/sha256.digest.ts +85 -0
@@ -0,0 +1,176 @@
1
+ /** The models the kiosk profile declares, by Better Auth model name. */
2
+ export declare const KIOSK_DEVICE_MODEL = "accessKioskDevice";
3
+ export declare const KIOSK_PIN_MODEL = "accessKioskPin";
4
+ export declare const KIOSK_LOCKOUT_MODEL = "accessKioskLockout";
5
+ export declare const KIOSK_RETIRED_MODEL = "accessKioskRetiredSecret";
6
+ /** The kiosk profile's tables and its session fields, in Better Auth's plugin schema form. */
7
+ export declare const kioskSchema: {
8
+ readonly accessKioskDevice: {
9
+ readonly fields: {
10
+ readonly name: {
11
+ readonly type: "string";
12
+ readonly required: true;
13
+ };
14
+ readonly secretHash: {
15
+ readonly type: "string";
16
+ readonly required: true;
17
+ readonly unique: true;
18
+ };
19
+ readonly previousSecretHash: {
20
+ readonly type: "string";
21
+ readonly required: false;
22
+ readonly index: true;
23
+ };
24
+ readonly rotatedAt: {
25
+ readonly type: "date";
26
+ readonly required: false;
27
+ };
28
+ readonly rotations: {
29
+ readonly type: "number";
30
+ readonly required: true;
31
+ };
32
+ readonly enrolledBy: {
33
+ readonly type: "string";
34
+ readonly required: true;
35
+ };
36
+ readonly createdAt: {
37
+ readonly type: "date";
38
+ readonly required: true;
39
+ };
40
+ readonly triesBackAt: {
41
+ readonly type: "number";
42
+ readonly required: true;
43
+ };
44
+ };
45
+ };
46
+ readonly accessKioskPin: {
47
+ readonly fields: {
48
+ readonly userId: {
49
+ readonly type: "string";
50
+ readonly required: true;
51
+ readonly unique: true;
52
+ readonly references: {
53
+ readonly model: "user";
54
+ readonly field: "id";
55
+ readonly onDelete: "cascade";
56
+ };
57
+ };
58
+ readonly pinHash: {
59
+ readonly type: "string";
60
+ readonly required: true;
61
+ };
62
+ readonly updatedAt: {
63
+ readonly type: "date";
64
+ readonly required: true;
65
+ };
66
+ };
67
+ };
68
+ readonly accessKioskLockout: {
69
+ readonly fields: {
70
+ readonly key: {
71
+ readonly type: "string";
72
+ readonly required: true;
73
+ readonly unique: true;
74
+ };
75
+ readonly deviceId: {
76
+ readonly type: "string";
77
+ readonly required: true;
78
+ readonly index: true;
79
+ readonly references: {
80
+ readonly model: "accessKioskDevice";
81
+ readonly field: "id";
82
+ readonly onDelete: "cascade";
83
+ };
84
+ };
85
+ readonly userId: {
86
+ readonly type: "string";
87
+ readonly required: true;
88
+ readonly index: true;
89
+ };
90
+ readonly failures: {
91
+ readonly type: "number";
92
+ readonly required: true;
93
+ };
94
+ readonly lastFailureAt: {
95
+ readonly type: "date";
96
+ readonly required: true;
97
+ };
98
+ };
99
+ };
100
+ readonly accessKioskRetiredSecret: {
101
+ readonly fields: {
102
+ readonly deviceId: {
103
+ readonly type: "string";
104
+ readonly required: true;
105
+ readonly index: true;
106
+ readonly references: {
107
+ readonly model: "accessKioskDevice";
108
+ readonly field: "id";
109
+ readonly onDelete: "cascade";
110
+ };
111
+ };
112
+ readonly secretHash: {
113
+ readonly type: "string";
114
+ readonly required: true;
115
+ readonly unique: true;
116
+ };
117
+ readonly retiredAt: {
118
+ readonly type: "date";
119
+ readonly required: true;
120
+ };
121
+ };
122
+ };
123
+ readonly session: {
124
+ readonly fields: {
125
+ readonly kioskDeviceId: {
126
+ readonly type: "string";
127
+ readonly required: false;
128
+ readonly input: false;
129
+ readonly index: true;
130
+ };
131
+ readonly kioskSeenAt: {
132
+ readonly type: "date";
133
+ readonly required: false;
134
+ readonly input: false;
135
+ };
136
+ readonly kioskPin: {
137
+ readonly type: "boolean";
138
+ readonly required: false;
139
+ readonly input: false;
140
+ };
141
+ };
142
+ };
143
+ };
144
+ /** An enrolled device, as its row holds it. */
145
+ export type KioskDeviceRow = {
146
+ readonly id: string;
147
+ readonly name: string;
148
+ readonly secretHash: string;
149
+ readonly previousSecretHash?: string | null;
150
+ readonly rotatedAt?: Date | string | null;
151
+ readonly rotations: number;
152
+ readonly enrolledBy: string;
153
+ readonly createdAt: Date | string;
154
+ /** When every PIN try the device spent is back, in whole seconds after `createdAt`. */
155
+ readonly triesBackAt: number;
156
+ };
157
+ /** A user's PIN, as its row holds it. */
158
+ export type KioskPinRow = {
159
+ readonly id: string;
160
+ readonly userId: string;
161
+ readonly pinHash: string;
162
+ };
163
+ /** One user's failed PINs on one device, as its row holds it. */
164
+ export type KioskLockoutRow = {
165
+ readonly id: string;
166
+ readonly key: string;
167
+ readonly failures: number;
168
+ readonly lastFailureAt: Date | string;
169
+ };
170
+ /** A retired device credential, as its row holds it. */
171
+ export type KioskRetiredRow = {
172
+ readonly id: string;
173
+ readonly deviceId: string;
174
+ readonly secretHash: string;
175
+ readonly retiredAt: Date | string;
176
+ };
@@ -0,0 +1,101 @@
1
+ // The kiosk profile's tables, declared through Better Auth's plugin schema as the
2
+ // registry's and the audit log's are: the Access plugin carries them with
3
+ // `profile: { kind: "kiosk" }`, so Better Auth's own migration (or its CLI's
4
+ // `generate` for an ORM's schema) creates them, and they are stored through whatever
5
+ // database adapter the app gave Better Auth.
6
+ //
7
+ // - `accessKioskDevice`: an enrolled device. Its credential is a random secret the
8
+ // device holds in an HTTP-only cookie; the table keeps its SHA-256 only, and the
9
+ // one before it (`previousSecretHash`), whose late answer is refused for a moment
10
+ // after a rotation; `rotations` counts the rotations. `triesBackAt` is when every
11
+ // PIN try the device spent is back, in seconds after its enrollment (`createdAt`).
12
+ // - `accessKioskRetiredSecret`: the device's token family, every credential a
13
+ // rotation retired (its SHA-256, and when): any of them brought back is a copy in
14
+ // use, and revokes the device. Deleted with its device.
15
+ // - `accessKioskPin`: a user's PIN, as an argon2id PHC string. Deleted with its user.
16
+ // - `accessKioskLockout`: failed PINs in a row for one user id on one device (`key`
17
+ // is `<deviceId>:<userId>`), whether or not that user holds a PIN. Deleted with its
18
+ // device.
19
+ // - Better Auth's `session` gains `kioskDeviceId`, the enrolled device a session was
20
+ // opened on and is bound to (a PIN switch's, or any sign-in's there), `kioskSeenAt`,
21
+ // when it was last used, and `kioskPin`, `true` for a session a PIN opened. A user
22
+ // cannot set any of them.
23
+ /** The models the kiosk profile declares, by Better Auth model name. */
24
+ export const KIOSK_DEVICE_MODEL = "accessKioskDevice";
25
+ export const KIOSK_PIN_MODEL = "accessKioskPin";
26
+ export const KIOSK_LOCKOUT_MODEL = "accessKioskLockout";
27
+ export const KIOSK_RETIRED_MODEL = "accessKioskRetiredSecret";
28
+ const optionalDate = { type: "date", required: false };
29
+ /** The kiosk profile's tables and its session fields, in Better Auth's plugin schema form. */
30
+ export const kioskSchema = {
31
+ [KIOSK_DEVICE_MODEL]: {
32
+ fields: {
33
+ name: { type: "string", required: true },
34
+ secretHash: { type: "string", required: true, unique: true },
35
+ previousSecretHash: { type: "string", required: false, index: true },
36
+ rotatedAt: optionalDate,
37
+ rotations: { type: "number", required: true },
38
+ enrolledBy: { type: "string", required: true },
39
+ createdAt: { type: "date", required: true },
40
+ triesBackAt: { type: "number", required: true },
41
+ },
42
+ },
43
+ [KIOSK_PIN_MODEL]: {
44
+ fields: {
45
+ userId: {
46
+ type: "string",
47
+ required: true,
48
+ unique: true,
49
+ references: { model: "user", field: "id", onDelete: "cascade" },
50
+ },
51
+ pinHash: { type: "string", required: true },
52
+ updatedAt: { type: "date", required: true },
53
+ },
54
+ },
55
+ [KIOSK_LOCKOUT_MODEL]: {
56
+ fields: {
57
+ key: { type: "string", required: true, unique: true },
58
+ deviceId: {
59
+ type: "string",
60
+ required: true,
61
+ index: true,
62
+ references: {
63
+ model: KIOSK_DEVICE_MODEL,
64
+ field: "id",
65
+ onDelete: "cascade",
66
+ },
67
+ },
68
+ userId: { type: "string", required: true, index: true },
69
+ failures: { type: "number", required: true },
70
+ lastFailureAt: { type: "date", required: true },
71
+ },
72
+ },
73
+ [KIOSK_RETIRED_MODEL]: {
74
+ fields: {
75
+ deviceId: {
76
+ type: "string",
77
+ required: true,
78
+ index: true,
79
+ references: {
80
+ model: KIOSK_DEVICE_MODEL,
81
+ field: "id",
82
+ onDelete: "cascade",
83
+ },
84
+ },
85
+ secretHash: { type: "string", required: true, unique: true },
86
+ retiredAt: { type: "date", required: true },
87
+ },
88
+ },
89
+ session: {
90
+ fields: {
91
+ kioskDeviceId: {
92
+ type: "string",
93
+ required: false,
94
+ input: false,
95
+ index: true,
96
+ },
97
+ kioskSeenAt: { type: "date", required: false, input: false },
98
+ kioskPin: { type: "boolean", required: false, input: false },
99
+ },
100
+ },
101
+ };
@@ -0,0 +1,171 @@
1
+ import { type KioskDeviceRow, type KioskPinRow } from "./kiosk.schema.js";
2
+ /**
3
+ * How long a device keeps its credential cookie, in seconds: 400 days, the most a
4
+ * browser keeps one. A retired credential older than this is forgotten at the
5
+ * device's next rotation: no browser still sends it.
6
+ */
7
+ export declare const DEVICE_COOKIE_MAX_AGE: number;
8
+ type Where = {
9
+ readonly field: string;
10
+ readonly value: unknown;
11
+ readonly operator?: string;
12
+ };
13
+ /** What the kiosk reads of Better Auth's database adapter. */
14
+ export type KioskAdapter = {
15
+ create(input: {
16
+ readonly model: string;
17
+ readonly data: {
18
+ readonly [field: string]: unknown;
19
+ };
20
+ }): Promise<unknown>;
21
+ findOne(input: {
22
+ readonly model: string;
23
+ readonly where: readonly Where[];
24
+ }): Promise<unknown>;
25
+ findMany(input: {
26
+ readonly model: string;
27
+ readonly where: readonly Where[];
28
+ readonly limit?: number;
29
+ readonly offset?: number;
30
+ readonly sortBy?: {
31
+ readonly field: string;
32
+ readonly direction: "asc";
33
+ };
34
+ }): Promise<unknown[]>;
35
+ update(input: {
36
+ readonly model: string;
37
+ readonly where: readonly Where[];
38
+ readonly update: {
39
+ readonly [field: string]: unknown;
40
+ };
41
+ }): Promise<unknown>;
42
+ updateMany(input: {
43
+ readonly model: string;
44
+ readonly where: readonly Where[];
45
+ readonly update: {
46
+ readonly [field: string]: unknown;
47
+ };
48
+ }): Promise<unknown>;
49
+ delete(input: {
50
+ readonly model: string;
51
+ readonly where: readonly Where[];
52
+ }): Promise<unknown>;
53
+ deleteMany(input: {
54
+ readonly model: string;
55
+ readonly where: readonly Where[];
56
+ }): Promise<unknown>;
57
+ incrementOne(input: {
58
+ readonly model: string;
59
+ readonly where: readonly Where[];
60
+ readonly increment: {
61
+ readonly [field: string]: number;
62
+ };
63
+ readonly set?: {
64
+ readonly [field: string]: unknown;
65
+ };
66
+ }): Promise<unknown>;
67
+ };
68
+ /** What the kiosk reads of Better Auth's sessions. */
69
+ type KioskSessions = {
70
+ deleteSessions(tokens: string[]): Promise<unknown>;
71
+ };
72
+ /** The device a request's credential names. */
73
+ export type DeviceCheck =
74
+ /** The device's secret now. */
75
+ {
76
+ readonly kind: "current";
77
+ readonly device: KioskDeviceRow;
78
+ }
79
+ /** The secret its last rotation retired, less than {@link ROTATION_GRACE} ago: a request that left before the answer. */
80
+ | {
81
+ readonly kind: "stale";
82
+ readonly device: KioskDeviceRow;
83
+ }
84
+ /** Any other secret of its token family: a copy in use. */
85
+ | {
86
+ readonly kind: "reused";
87
+ readonly device: KioskDeviceRow;
88
+ };
89
+ /** An enrolled device, as the operator's API and the `listDevices` verb show it: never a secret. */
90
+ export type AccessKioskDevice = {
91
+ readonly id: string;
92
+ readonly name: string;
93
+ /** The user who enrolled it. */
94
+ readonly enrolledBy: string;
95
+ readonly enrolledAt: Date;
96
+ /** The last PIN switch on it (its credential's last rotation); `null` before the first. */
97
+ readonly lastSwitchAt: Date | null;
98
+ };
99
+ /** A refusal for now, with the seconds until a try is let through again. */
100
+ type Held = {
101
+ readonly retryAfter: number;
102
+ };
103
+ /** Why a user's try on a device is not let through: their backoff, or their PIN disabled there. */
104
+ export type PairHeld = {
105
+ readonly kind: "wait";
106
+ readonly retryAfter: number;
107
+ } | {
108
+ readonly kind: "disabled";
109
+ };
110
+ /** The kiosk's store over Better Auth's adapter and sessions. */
111
+ export declare const kioskStore: (adapter: KioskAdapter, sessions: KioskSessions, now?: () => number) => {
112
+ /** The device a credential names, read from its hash; `undefined` for none. */
113
+ check: (secret: unknown) => Promise<DeviceCheck | undefined>;
114
+ /** Enrolls a device: its row, and the secret it is handed (once). */
115
+ enroll: (input: {
116
+ readonly name: string;
117
+ readonly enrolledBy: string;
118
+ }) => Promise<{
119
+ readonly device: KioskDeviceRow;
120
+ readonly secret: string;
121
+ }>;
122
+ /**
123
+ * Gives the device a new secret, in place of the one it brought; `undefined` when
124
+ * another request rotated it first (that one's secret is the device's now).
125
+ */
126
+ rotate: (from: KioskDeviceRow) => Promise<string | undefined>;
127
+ /** Revokes a device: every session on it ended, its counts and its row deleted. */
128
+ revoke: (deviceId: string) => Promise<boolean>;
129
+ sessionsOn: (deviceId: string) => Promise<string[]>;
130
+ endSessionsOn: (deviceId: string) => Promise<number>;
131
+ /** Every enrolled device, oldest first, as a manager sees it. */
132
+ devices: () => Promise<AccessKioskDevice[]>;
133
+ /** A user's PIN, as its hash; `undefined` when they have none. */
134
+ pinOf: (userId: string) => Promise<KioskPinRow | undefined>;
135
+ /** Sets a user's PIN hash, and clears their failed PINs on every device. */
136
+ setPin: (userId: string, pinHash: string) => Promise<void>;
137
+ /**
138
+ * Replaces a user's PIN hash with the same PIN hashed anew, only while the row
139
+ * still holds `from` (a compare-and-set): a PIN set meanwhile stays. Their failed
140
+ * PINs are left as they are.
141
+ */
142
+ rehashPin: (userId: string, from: string, pinHash: string) => Promise<void>;
143
+ /** Clears a user's failed PINs on every device (a full sign-in proves who they are). */
144
+ clearUser: (userId: string) => Promise<void>;
145
+ /** Whether a user's next try on a device waits, and why; `undefined` when it may go. */
146
+ pairHeld: (deviceId: string, userId: string) => Promise<PairHeld | undefined>;
147
+ /**
148
+ * Counts a try at a user's PIN on a device, before it is checked; held when
149
+ * the user's backoff on that device has not passed, or their PIN is disabled
150
+ * there (counted by another request meanwhile).
151
+ */
152
+ reservePair: (deviceId: string, userId: string) => Promise<PairHeld | undefined>;
153
+ /**
154
+ * Counts a user's first try on a device since their last right PIN there, and
155
+ * only that one: `false` when they have a failure there already (counted by
156
+ * another request meanwhile included). What a held device lets through.
157
+ */
158
+ reserveFirstPair: (deviceId: string, userId: string) => Promise<boolean>;
159
+ /** Clears a user's failed PINs on a device: their PIN matched there. */
160
+ clearPair: (deviceId: string, userId: string) => Promise<void>;
161
+ /**
162
+ * Counts a try on a device, before the PIN is checked; held when the device's
163
+ * tries are spent ({@link KIOSK_DEVICE_FAILURES}): `max` at once, one back every
164
+ * `window / max` seconds.
165
+ */
166
+ reserveDevice: (deviceId: string) => Promise<Held | undefined>;
167
+ /** Gives back a try counted on a device: its PIN matched. */
168
+ releaseDevice: (deviceId: string) => Promise<void>;
169
+ };
170
+ export type KioskStore = ReturnType<typeof kioskStore>;
171
+ export {};