@spfn/auth 0.2.0-beta.87 → 0.2.0-beta.89
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 +384 -18
- package/dist/{authenticate-C7w-pLOR.d.ts → authenticate-DK-hLSOW.d.ts} +154 -5
- package/dist/client-proof.d.ts +122 -2
- package/dist/client-proof.js +366 -5
- package/dist/client-proof.js.map +1 -1
- package/dist/config.d.ts +36 -0
- package/dist/config.js +18 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +93 -2
- package/dist/errors.js +57 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +32 -3
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +2 -2
- package/dist/server.d.ts +126 -11
- package/dist/server.js +527 -106
- package/dist/server.js.map +1 -1
- package/dist/{session-CGxgH3C9.d.ts → session-CFK4BT25.d.ts} +1 -1
- package/dist/{types-1BMx0OX1.d.ts → types-CD95yudz.d.ts} +15 -1
- package/migrations/20251125021229_premium_famine/snapshot.json +2641 -0
- package/migrations/20260225130050_smooth_the_fury/snapshot.json +2686 -0
- package/migrations/20260308141417_deep_iceman/snapshot.json +2686 -0
- package/migrations/20260308151309_perfect_deathbird/snapshot.json +2731 -0
- package/migrations/20260308201135_concerned_rawhide_kid/snapshot.json +2786 -0
- package/migrations/20260629103209_lethal_lifeguard/snapshot.json +2786 -0
- package/migrations/20260709073531_easy_hardball/snapshot.json +3119 -0
- package/migrations/20260714081434_glossy_major_mapleleaf/snapshot.json +3112 -0
- package/migrations/20260804105939_amazing_bushwacker/migration.sql +3 -0
- package/migrations/20260804105939_amazing_bushwacker/snapshot.json +3112 -0
- package/migrations/20260804110033_fat_piledriver/migration.sql +2 -0
- package/migrations/20260804110033_fat_piledriver/snapshot.json +3138 -0
- package/package.json +3 -6
- package/migrations/meta/0000_snapshot.json +0 -1632
- package/migrations/meta/0001_snapshot.json +0 -1660
- package/migrations/meta/0002_snapshot.json +0 -1660
- package/migrations/meta/0003_snapshot.json +0 -1689
- package/migrations/meta/0004_snapshot.json +0 -1721
- package/migrations/meta/0005_snapshot.json +0 -1721
- package/migrations/meta/0006_snapshot.json +0 -1921
- package/migrations/meta/0007_snapshot.json +0 -1916
- package/migrations/meta/_journal.json +0 -62
- /package/migrations/{0000_premium_famine.sql → 20251125021229_premium_famine/migration.sql} +0 -0
- /package/migrations/{0001_smooth_the_fury.sql → 20260225130050_smooth_the_fury/migration.sql} +0 -0
- /package/migrations/{0002_deep_iceman.sql → 20260308141417_deep_iceman/migration.sql} +0 -0
- /package/migrations/{0003_perfect_deathbird.sql → 20260308151309_perfect_deathbird/migration.sql} +0 -0
- /package/migrations/{0004_concerned_rawhide_kid.sql → 20260308201135_concerned_rawhide_kid/migration.sql} +0 -0
- /package/migrations/{0005_lethal_lifeguard.sql → 20260629103209_lethal_lifeguard/migration.sql} +0 -0
- /package/migrations/{0006_easy_hardball.sql → 20260709073531_easy_hardball/migration.sql} +0 -0
- /package/migrations/{0007_glossy_major_mapleleaf.sql → 20260714081434_glossy_major_mapleleaf/migration.sql} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _spfn_core_route from '@spfn/core/route';
|
|
2
|
-
import { K as KeyAlgorithmType,
|
|
2
|
+
import { K as KeyAlgorithmType, d as KeyPlatformType, h as SocialProvider } from './types-CD95yudz.js';
|
|
3
3
|
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
4
4
|
import { Static } from '@sinclair/typebox';
|
|
5
5
|
import { Context } from 'hono';
|
|
@@ -101,6 +101,8 @@ interface RegisterParams {
|
|
|
101
101
|
keyId: string;
|
|
102
102
|
fingerprint: string;
|
|
103
103
|
algorithm?: KeyAlgorithmType;
|
|
104
|
+
deviceName?: string;
|
|
105
|
+
platform?: KeyPlatformType;
|
|
104
106
|
metadata?: Record<string, unknown>;
|
|
105
107
|
}
|
|
106
108
|
interface RegisterResult {
|
|
@@ -118,6 +120,8 @@ interface LoginParams {
|
|
|
118
120
|
fingerprint: string;
|
|
119
121
|
oldKeyId?: string;
|
|
120
122
|
algorithm?: KeyAlgorithmType;
|
|
123
|
+
deviceName?: string;
|
|
124
|
+
platform?: KeyPlatformType;
|
|
121
125
|
}
|
|
122
126
|
interface LoginResult {
|
|
123
127
|
userId: string;
|
|
@@ -155,6 +159,16 @@ declare function changePasswordService(params: ChangePasswordParams): Promise<vo
|
|
|
155
159
|
|
|
156
160
|
declare const EmailSchema: _sinclair_typebox.TString;
|
|
157
161
|
declare const PhoneSchema: _sinclair_typebox.TString;
|
|
162
|
+
/**
|
|
163
|
+
* Optional device labels a client may send when registering a key.
|
|
164
|
+
*
|
|
165
|
+
* Display only: the key list uses them to tell one device from another, and
|
|
166
|
+
* nothing is authorized or refused by either value, so a client that lies about
|
|
167
|
+
* them gains nothing. Both are omitted by every key registered before they
|
|
168
|
+
* existed, hence optional rather than defaulted.
|
|
169
|
+
*/
|
|
170
|
+
declare const DeviceNameSchema: _sinclair_typebox.TString;
|
|
171
|
+
declare const PlatformSchema: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>;
|
|
158
172
|
declare const PasswordSchema: _sinclair_typebox.TString;
|
|
159
173
|
declare const TargetTypeSchema: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">]>;
|
|
160
174
|
type VerificationTargetType = Static<typeof TargetTypeSchema>;
|
|
@@ -212,6 +226,9 @@ interface RegisterPublicKeyParams {
|
|
|
212
226
|
publicKey: string;
|
|
213
227
|
fingerprint: string;
|
|
214
228
|
algorithm?: KeyAlgorithmType;
|
|
229
|
+
/** Device label for the key list. Display only — nothing is authorized by it. */
|
|
230
|
+
deviceName?: string;
|
|
231
|
+
platform?: KeyPlatformType;
|
|
215
232
|
}
|
|
216
233
|
interface RotateKeyParams {
|
|
217
234
|
userId: number;
|
|
@@ -220,6 +237,9 @@ interface RotateKeyParams {
|
|
|
220
237
|
newPublicKey: string;
|
|
221
238
|
fingerprint: string;
|
|
222
239
|
algorithm?: KeyAlgorithmType;
|
|
240
|
+
/** Omitted: the replaced key's label carries over, so rotation keeps its name. */
|
|
241
|
+
deviceName?: string;
|
|
242
|
+
platform?: KeyPlatformType;
|
|
223
243
|
}
|
|
224
244
|
interface RotateKeyResult {
|
|
225
245
|
success: boolean;
|
|
@@ -230,8 +250,61 @@ interface RevokeKeyParams {
|
|
|
230
250
|
keyId: string;
|
|
231
251
|
reason: string;
|
|
232
252
|
}
|
|
253
|
+
interface RevokeAllKeysParams {
|
|
254
|
+
userId: number;
|
|
255
|
+
/** The key the request itself is signed with — spared unless includeCurrent. */
|
|
256
|
+
currentKeyId: string;
|
|
257
|
+
/** true signs the caller out too. Default false: "my other devices". */
|
|
258
|
+
includeCurrent?: boolean;
|
|
259
|
+
reason: string;
|
|
260
|
+
}
|
|
261
|
+
interface RevokeAllKeysResult {
|
|
262
|
+
revokedCount: number;
|
|
263
|
+
currentKeyRevoked: boolean;
|
|
264
|
+
}
|
|
265
|
+
/** One registered device as the account surface shows it. */
|
|
266
|
+
interface KeySummary {
|
|
267
|
+
keyId: string;
|
|
268
|
+
deviceName?: string;
|
|
269
|
+
platform?: string;
|
|
270
|
+
algorithm: KeyAlgorithmType;
|
|
271
|
+
/** First bytes of the fingerprint — enough to tell two entries apart. */
|
|
272
|
+
fingerprintPrefix: string;
|
|
273
|
+
/**
|
|
274
|
+
* Milliseconds since the Unix epoch, not an ISO string.
|
|
275
|
+
*
|
|
276
|
+
* One representation of a moment across the whole surface: a generated Swift
|
|
277
|
+
* or Kotlin client reads an integer with no date formatter, and
|
|
278
|
+
* `ISO8601DateFormatter` rejecting fractional seconds by default stops being
|
|
279
|
+
* a way for the two SDKs to disagree about the same value.
|
|
280
|
+
*/
|
|
281
|
+
createdAtMillis: number;
|
|
282
|
+
lastUsedAtMillis?: number;
|
|
283
|
+
expiresAtMillis?: number;
|
|
284
|
+
/** The TTL has run out. The key still reads as active; authenticate refuses it. */
|
|
285
|
+
isExpired: boolean;
|
|
286
|
+
/** False once revoked. Only ever false when the caller asked for revoked keys. */
|
|
287
|
+
isActive: boolean;
|
|
288
|
+
/** When it was revoked, for the "what did I cut off, and when" reading. */
|
|
289
|
+
revokedAtMillis?: number;
|
|
290
|
+
}
|
|
291
|
+
interface ListKeysParams {
|
|
292
|
+
userId: number;
|
|
293
|
+
/** Also return keys already revoked. Default false: only what can still sign. */
|
|
294
|
+
includeRevoked?: boolean;
|
|
295
|
+
}
|
|
296
|
+
/** How much of the fingerprint the list returns. */
|
|
297
|
+
declare const KEY_FINGERPRINT_PREFIX_LENGTH = 8;
|
|
233
298
|
/**
|
|
234
299
|
* Register a new public key for a user
|
|
300
|
+
*
|
|
301
|
+
* `keyId` is UNIQUE across all users, so the lookup must ignore `isActive` —
|
|
302
|
+
* filtering on it misses a revoked row and the insert then fails on the unique
|
|
303
|
+
* index, rolling the whole login transaction back into a 500. Reuse is refused
|
|
304
|
+
* with a domain error instead, telling the client to generate a fresh keyId.
|
|
305
|
+
*
|
|
306
|
+
* @throws KeyIdAlreadyRegisteredError keyId가 이미 쓰인 값일 때 (자기 폐기 키 재사용 · 남의 키)
|
|
307
|
+
* @throws InvalidKeyFingerprintError fingerprint가 publicKey와 맞지 않을 때
|
|
235
308
|
*/
|
|
236
309
|
declare function registerPublicKeyService(params: RegisterPublicKeyParams): Promise<void>;
|
|
237
310
|
/**
|
|
@@ -239,9 +312,36 @@ declare function registerPublicKeyService(params: RegisterPublicKeyParams): Prom
|
|
|
239
312
|
*/
|
|
240
313
|
declare function rotateKeyService(params: RotateKeyParams): Promise<RotateKeyResult>;
|
|
241
314
|
/**
|
|
242
|
-
* Revoke a user's public key
|
|
315
|
+
* Revoke a user's public key.
|
|
316
|
+
*
|
|
317
|
+
* Returns false when the key does not belong to this user, so a caller acting
|
|
318
|
+
* on a key id from outside (the device list) can answer "not found" instead of
|
|
319
|
+
* reporting a revocation that never happened. The repository already scopes the
|
|
320
|
+
* update by userId, so someone else's key is never touched either way.
|
|
321
|
+
*/
|
|
322
|
+
declare function revokeKeyService(params: RevokeKeyParams): Promise<boolean>;
|
|
323
|
+
/**
|
|
324
|
+
* List the caller's active keys — one entry per device that can sign for them.
|
|
325
|
+
*
|
|
326
|
+
* `isExpired` is computed rather than stored: an expired key keeps `isActive`
|
|
327
|
+
* true (nothing flips it), and `authenticate` refuses it at request time. A list
|
|
328
|
+
* that showed it as simply "active" would be telling the user something the
|
|
329
|
+
* server does not act on.
|
|
330
|
+
*
|
|
331
|
+
* The fingerprint is truncated. Its full value is what a native sign-in must
|
|
332
|
+
* send as its nonce (issue #63), and an account page has no use for it beyond
|
|
333
|
+
* telling two entries apart.
|
|
243
334
|
*/
|
|
244
|
-
declare function
|
|
335
|
+
declare function listKeysService(params: ListKeysParams): Promise<KeySummary[]>;
|
|
336
|
+
/**
|
|
337
|
+
* Revoke every active key the user has, optionally sparing the current one.
|
|
338
|
+
*
|
|
339
|
+
* The caller's own key is spared by default, so "sign out my other devices"
|
|
340
|
+
* does not also end the session making the request. Passing
|
|
341
|
+
* `includeCurrent: true` is the full sign-out, which until now was reachable
|
|
342
|
+
* only as a side effect of changing a password.
|
|
343
|
+
*/
|
|
344
|
+
declare function revokeAllKeysService(params: RevokeAllKeysParams): Promise<RevokeAllKeysResult>;
|
|
245
345
|
|
|
246
346
|
/**
|
|
247
347
|
* @spfn/auth - RBAC Type Definitions
|
|
@@ -392,6 +492,16 @@ interface OAuthTokens {
|
|
|
392
492
|
interface NativeVerifyOptions {
|
|
393
493
|
/** 클라이언트가 생성한 raw nonce. provider별 규약(raw 또는 SHA-256 해시)으로 대조된다. */
|
|
394
494
|
nonce: string;
|
|
495
|
+
/**
|
|
496
|
+
* 같은 로그인에서 SDK가 함께 받은 provider access token (선택).
|
|
497
|
+
*
|
|
498
|
+
* id_token만으로는 알 수 없는 claim을 provider API로 보강하려는 provider가 쓴다
|
|
499
|
+
* (카카오: id_token에 email_verified가 없어 /v2/user/me의 이메일 유효·인증 플래그를 본다).
|
|
500
|
+
*
|
|
501
|
+
* ⚠️ 클라이언트가 보낸 검증되지 않은 값이다. 다른 사용자의 토큰일 수 있으므로,
|
|
502
|
+
* 이 값으로 조회한 신원은 반드시 id_token의 sub와 대조한 뒤에만 신뢰해야 한다.
|
|
503
|
+
*/
|
|
504
|
+
accessToken?: string;
|
|
395
505
|
}
|
|
396
506
|
interface OAuthCodeExchangeOptions {
|
|
397
507
|
/** Provider가 callback에 돌려준 원본 state. 일부 provider는 token 교환에도 요구한다. */
|
|
@@ -621,6 +731,16 @@ interface OAuthNativeParams {
|
|
|
621
731
|
keyId: string;
|
|
622
732
|
fingerprint: string;
|
|
623
733
|
algorithm: KeyAlgorithmType;
|
|
734
|
+
/** 키 목록에 보일 기기 라벨 (선택). 표시용이라 권한 판정에 쓰이지 않는다. */
|
|
735
|
+
deviceName?: string;
|
|
736
|
+
platform?: KeyPlatformType;
|
|
737
|
+
/**
|
|
738
|
+
* SDK가 id_token과 함께 받은 provider access token (선택).
|
|
739
|
+
*
|
|
740
|
+
* provider가 id_token만으로 확인할 수 없는 claim을 보강할 때만 쓴다. 없으면 provider는
|
|
741
|
+
* id_token이 담은 정보만으로 신원을 정규화한다.
|
|
742
|
+
*/
|
|
743
|
+
accessToken?: string;
|
|
624
744
|
/** Apple은 첫 로그인에만 이름을 별도로 주므로 클라이언트가 전달할 수 있다. */
|
|
625
745
|
profile?: {
|
|
626
746
|
name?: string;
|
|
@@ -635,7 +755,7 @@ interface OAuthNativeResult {
|
|
|
635
755
|
/**
|
|
636
756
|
* native id_token 로그인 처리
|
|
637
757
|
*
|
|
638
|
-
* @throws
|
|
758
|
+
* @throws NativeSignInUnsupportedError provider가 native sign-in을 지원하지 않을 때
|
|
639
759
|
* @throws InvalidSocialTokenError id_token 검증 실패 시
|
|
640
760
|
*/
|
|
641
761
|
declare function oauthNativeService(params: OAuthNativeParams): Promise<OAuthNativeResult>;
|
|
@@ -690,6 +810,8 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
|
|
|
690
810
|
keyId: _sinclair_typebox.TString;
|
|
691
811
|
fingerprint: _sinclair_typebox.TString;
|
|
692
812
|
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
813
|
+
deviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
814
|
+
platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
|
|
693
815
|
}>;
|
|
694
816
|
}, RegisterResult>;
|
|
695
817
|
login: _spfn_core_route.RouteDef<{
|
|
@@ -705,6 +827,8 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
|
|
|
705
827
|
fingerprint: _sinclair_typebox.TString;
|
|
706
828
|
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
707
829
|
oldKeyId: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
830
|
+
deviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
831
|
+
platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
|
|
708
832
|
}>;
|
|
709
833
|
}, LoginResult>;
|
|
710
834
|
logout: _spfn_core_route.RouteDef<{}, {}, void>;
|
|
@@ -714,8 +838,30 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
|
|
|
714
838
|
keyId: _sinclair_typebox.TString;
|
|
715
839
|
fingerprint: _sinclair_typebox.TString;
|
|
716
840
|
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
841
|
+
deviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
842
|
+
platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
|
|
717
843
|
}>;
|
|
718
844
|
}, RotateKeyResult>;
|
|
845
|
+
listKeys: _spfn_core_route.RouteDef<{
|
|
846
|
+
body: _sinclair_typebox.TObject<{
|
|
847
|
+
includeRevoked: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
|
|
848
|
+
}>;
|
|
849
|
+
}, {}, {
|
|
850
|
+
keys: KeySummary[];
|
|
851
|
+
}>;
|
|
852
|
+
revokeKey: _spfn_core_route.RouteDef<{
|
|
853
|
+
body: _sinclair_typebox.TObject<{
|
|
854
|
+
keyId: _sinclair_typebox.TString;
|
|
855
|
+
}>;
|
|
856
|
+
}, {}, {
|
|
857
|
+
keyId: string;
|
|
858
|
+
selfRevoked: boolean;
|
|
859
|
+
}>;
|
|
860
|
+
revokeAllKeys: _spfn_core_route.RouteDef<{
|
|
861
|
+
body: _sinclair_typebox.TObject<{
|
|
862
|
+
includeCurrent: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
|
|
863
|
+
}>;
|
|
864
|
+
}, {}, RevokeAllKeysResult>;
|
|
719
865
|
changePassword: _spfn_core_route.RouteDef<{
|
|
720
866
|
body: _sinclair_typebox.TObject<{
|
|
721
867
|
currentPassword: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
@@ -847,10 +993,13 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
|
|
|
847
993
|
body: _sinclair_typebox.TObject<{
|
|
848
994
|
idToken: _sinclair_typebox.TString;
|
|
849
995
|
nonce: _sinclair_typebox.TString;
|
|
996
|
+
accessToken: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
850
997
|
publicKey: _sinclair_typebox.TString;
|
|
851
998
|
keyId: _sinclair_typebox.TString;
|
|
852
999
|
fingerprint: _sinclair_typebox.TString;
|
|
853
1000
|
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
1001
|
+
deviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
1002
|
+
platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
|
|
854
1003
|
profile: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
|
|
855
1004
|
name: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
856
1005
|
}>>;
|
|
@@ -1231,4 +1380,4 @@ declare const authenticate: _spfn_core_route.NamedMiddleware<"auth">;
|
|
|
1231
1380
|
*/
|
|
1232
1381
|
declare const optionalAuth: _spfn_core_route.NamedMiddleware<"optionalAuth">;
|
|
1233
1382
|
|
|
1234
|
-
export {
|
|
1383
|
+
export { requireEnabledProvider as $, type AuthSession as A, registerPublicKeyService as B, type ChangePasswordParams as C, rotateKeyService as D, revokeKeyService as E, listKeysService as F, revokeAllKeysService as G, KEY_FINGERPRINT_PREFIX_LENGTH as H, type IssueOneTimeTokenResult as I, type RegisterPublicKeyParams as J, type KeySummary as K, type LoginResult as L, type RotateKeyParams as M, type RevokeKeyParams as N, type OAuthStartResult as O, type PermissionConfig as P, type RevokeAllKeysParams as Q, type RoleConfig as R, type SendVerificationCodeResult as S, issueOneTimeTokenService as T, type UserProfile as U, type VerificationTargetType as V, verifyOneTimeTokenService as W, oauthStartService as X, oauthCallbackService as Y, buildOAuthErrorUrl as Z, isOAuthProviderEnabled as _, type RegisterResult as a, getEnabledOAuthProviders as a0, getGoogleAccessToken as a1, oauthUnlinkNotifyService as a2, type OAuthStartParams as a3, type OAuthCallbackParams as a4, type OAuthCallbackResult as a5, type UnlinkNotifyResult as a6, oauthNativeService as a7, type OAuthNativeParams as a8, selectAuthProfile as a9, resolveAuthenticatedUser as aa, type AuthProfileVerifier as ab, authenticate as ac, optionalAuth as ad, EmailSchema as ae, PhoneSchema as af, DeviceNameSchema as ag, PlatformSchema as ah, PasswordSchema as ai, TargetTypeSchema as aj, VerificationPurposeSchema as ak, type NormalizedIdentity as al, type OAuthTokens as am, type NativeVerifyOptions as an, type OAuthCodeExchangeOptions as ao, type UnlinkNotifyRequest as ap, type UnlinkNotification as aq, UnlinkNotifyRejection as ar, registerOAuthProvider as as, getOAuthProvider as at, getRegisteredProviders as au, type RotateKeyResult as b, type RevokeAllKeysResult as c, type OAuthNativeResult as d, type ProfileInfo as e, type VerificationPurpose as f, VERIFICATION_TARGET_TYPES as g, VERIFICATION_PURPOSES as h, PERMISSION_CATEGORIES as i, type PermissionCategory as j, type AuthInitOptions as k, type OAuthProvider as l, mainAuthRouter as m, type AuthContext as n, loginService as o, logoutService as p, changePasswordService as q, registerService as r, type RegisterParams as s, type LoginParams as t, type LogoutParams as u, sendVerificationCodeService as v, verifyCodeService as w, type SendVerificationCodeParams as x, type VerifyCodeParams as y, type VerifyCodeResult as z };
|
package/dist/client-proof.d.ts
CHANGED
|
@@ -149,6 +149,14 @@ declare class ClientProofRefusal {
|
|
|
149
149
|
static bodyNotTheDeclaredType(): ClientProofRefusal;
|
|
150
150
|
static sessionHeaderMisplaced(): ClientProofRefusal;
|
|
151
151
|
static unprocessable(): ClientProofRefusal;
|
|
152
|
+
/**
|
|
153
|
+
* A client that ships separately from the server said nothing about which
|
|
154
|
+
* contract it was built against. Without it the server cannot tell whether
|
|
155
|
+
* the two ends agree, and answering as though they do is what produces the
|
|
156
|
+
* undecodable body this check exists to replace.
|
|
157
|
+
*/
|
|
158
|
+
static contractVersionMissing(): ClientProofRefusal;
|
|
159
|
+
static contractVersionUnsupported(): ClientProofRefusal;
|
|
152
160
|
static profileRejected(): ClientProofRefusal;
|
|
153
161
|
static sessionRevoked(): ClientProofRefusal;
|
|
154
162
|
static proofExpired(): ClientProofRefusal;
|
|
@@ -430,7 +438,7 @@ declare function getClientProofReplayStore(): ClientProofReplayStore;
|
|
|
430
438
|
*/
|
|
431
439
|
|
|
432
440
|
interface ContractOperation {
|
|
433
|
-
id: 'auth.clientProof.handshake' | 'echo.send' | 'items.list' | 'auth.enroll.register' | 'auth.enroll.login' | 'auth.enroll.oauthNative' | 'auth.keys.rotate';
|
|
441
|
+
id: 'auth.clientProof.handshake' | 'echo.send' | 'items.list' | 'auth.enroll.register' | 'auth.enroll.login' | 'auth.enroll.oauthNative' | 'auth.keys.rotate' | 'auth.keys.list' | 'auth.keys.revoke' | 'auth.keys.revokeAll';
|
|
434
442
|
method: 'POST';
|
|
435
443
|
path: string;
|
|
436
444
|
/**
|
|
@@ -554,4 +562,116 @@ interface ClientProofGuardOptions {
|
|
|
554
562
|
*/
|
|
555
563
|
declare function createClientProofGuard(state: ClientProofState, options?: ClientProofGuardOptions): MiddlewareHandler;
|
|
556
564
|
|
|
557
|
-
|
|
565
|
+
/**
|
|
566
|
+
* The header names each end announces itself under.
|
|
567
|
+
*
|
|
568
|
+
* Separated from the logic that reads them so the contract bundle can name them
|
|
569
|
+
* without importing the version comparison, which reads the bundle back. These
|
|
570
|
+
* are declarations and depend on nothing.
|
|
571
|
+
*
|
|
572
|
+
* @module server/client-proof/wire-headers
|
|
573
|
+
*/
|
|
574
|
+
/** What a client says about itself, one header each. */
|
|
575
|
+
declare const CLIENT_IDENTITY_HEADERS: {
|
|
576
|
+
readonly kind: "x-spfn-client-kind";
|
|
577
|
+
readonly version: "x-spfn-client-version";
|
|
578
|
+
readonly contractVersion: "x-spfn-client-contract-version";
|
|
579
|
+
};
|
|
580
|
+
/**
|
|
581
|
+
* What the server says about itself, on every response.
|
|
582
|
+
*
|
|
583
|
+
* Distinct names from the request headers on purpose: a proxy that echoes a
|
|
584
|
+
* request header into the response would otherwise make the client's own
|
|
585
|
+
* version look like the server's.
|
|
586
|
+
*/
|
|
587
|
+
declare const SERVER_CONTRACT_HEADERS: {
|
|
588
|
+
readonly version: "x-spfn-server-contract-version";
|
|
589
|
+
readonly supportedRange: "x-spfn-supported-contract-range";
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
* The client kinds the server distinguishes.
|
|
593
|
+
*
|
|
594
|
+
* `web` is separated from the two app kinds because it carries no contract
|
|
595
|
+
* version: a browser bundle is deployed with the server that serves it, so
|
|
596
|
+
* there is no second version to reconcile.
|
|
597
|
+
*/
|
|
598
|
+
declare const CLIENT_KINDS: readonly ["web", "ios", "android"];
|
|
599
|
+
type ClientKind = typeof CLIENT_KINDS[number];
|
|
600
|
+
/** A kind that ships independently of the server, so its contract version matters. */
|
|
601
|
+
declare function isAppKind(kind: ClientKind): boolean;
|
|
602
|
+
|
|
603
|
+
/** What one request announced about the client that sent it. */
|
|
604
|
+
interface ClientIdentity {
|
|
605
|
+
kind: ClientKind;
|
|
606
|
+
/** The client's own release — a store version, or a bundle build. */
|
|
607
|
+
version: string | null;
|
|
608
|
+
/** The contract version the client was generated from. Never set for `web`. */
|
|
609
|
+
contractVersion: string | null;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Reads the identity headers, or null when the kind is absent or unrecognised.
|
|
613
|
+
*
|
|
614
|
+
* Null is not by itself a refusal — a request from something that predates
|
|
615
|
+
* these headers reaches here too. `judgeClientIdentity` decides.
|
|
616
|
+
*/
|
|
617
|
+
declare function readClientIdentity(headers: Headers): ClientIdentity | null;
|
|
618
|
+
/**
|
|
619
|
+
* Whether the server serves what the client was generated against.
|
|
620
|
+
*
|
|
621
|
+
* Under 0.x the minor carries breaking changes, so a supported client agrees on
|
|
622
|
+
* major and minor. From 1.0.0 the major alone decides. This is the rule
|
|
623
|
+
* `CONTRACT_SUPPORTED_RANGE` spells out; keeping it as a comparison rather than
|
|
624
|
+
* parsing that string leaves one place to change when the line reaches 1.0.0.
|
|
625
|
+
*/
|
|
626
|
+
declare function isContractVersionSupported(clientVersion: string): boolean;
|
|
627
|
+
/**
|
|
628
|
+
* The refusal a request's announced identity earns, or null to let it through.
|
|
629
|
+
*
|
|
630
|
+
* An app kind must state a contract version this server serves. A version it
|
|
631
|
+
* does not serve, and the absence of one, are the same answer: the two ends do
|
|
632
|
+
* not agree on what the contract is, which is what CONTRACT_UNSUPPORTED means.
|
|
633
|
+
* The response carries the server's version and range, so the client can say
|
|
634
|
+
* which way the gap runs.
|
|
635
|
+
*
|
|
636
|
+
* `web` is exempt from the contract check by construction, not by leniency.
|
|
637
|
+
*
|
|
638
|
+
* A request with no recognised kind passes. The check is on what a client says
|
|
639
|
+
* about itself, and a caller that says nothing — a curl, a health probe, a
|
|
640
|
+
* server-to-server call — is not a deployed client this rule is about.
|
|
641
|
+
*/
|
|
642
|
+
declare function judgeClientIdentity(identity: ClientIdentity | null): ClientProofRefusal | null;
|
|
643
|
+
/** Writes the server's own announcement onto a response's headers. */
|
|
644
|
+
declare function applyServerContractHeaders(headers: Headers): void;
|
|
645
|
+
/** The same announcement as a plain object, for a response built from one. */
|
|
646
|
+
declare function serverContractHeaders(): Record<string, string>;
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* The version announcement, applied to every request rather than to the proven
|
|
650
|
+
* ones.
|
|
651
|
+
*
|
|
652
|
+
* Enrollment and login are the first calls a client makes and they carry no
|
|
653
|
+
* proof — there is no key to sign with yet. A check that lives inside proof
|
|
654
|
+
* admission therefore never sees the client it is meant to catch: an outdated
|
|
655
|
+
* app fails at login, before it reaches anything proven. This runs ahead of all
|
|
656
|
+
* of it.
|
|
657
|
+
*
|
|
658
|
+
* hono is imported as types only, so this module adds no runtime dependency.
|
|
659
|
+
*
|
|
660
|
+
* @module server/client-proof/version-middleware
|
|
661
|
+
*/
|
|
662
|
+
|
|
663
|
+
/** The context key the identity is left under, for a handler that wants it. */
|
|
664
|
+
declare const CLIENT_IDENTITY_CONTEXT_KEY = "clientIdentity";
|
|
665
|
+
/**
|
|
666
|
+
* Announces the server's contract version on every response and refuses a
|
|
667
|
+
* client whose own contract version this server does not serve.
|
|
668
|
+
*
|
|
669
|
+
* The announcement goes out either way. A refused client needs it most — the
|
|
670
|
+
* refusal says the two ends disagree, and the range is what says how.
|
|
671
|
+
*
|
|
672
|
+
* Mount this before authentication, not after: the point is to answer a stale
|
|
673
|
+
* client before anything else has a chance to fail confusingly.
|
|
674
|
+
*/
|
|
675
|
+
declare function createClientVersionMiddleware(): MiddlewareHandler;
|
|
676
|
+
|
|
677
|
+
export { ABSENT_BODY_SHA256, AUTH_SURFACE_OPERATIONS, type Admission, CLIENT_IDENTITY_CONTEXT_KEY, CLIENT_IDENTITY_HEADERS, CLIENT_KINDS, CLIENT_PROOF_CONTENT_TYPE, CLIENT_PROOF_HEADERS, CLIENT_PROOF_PROFILE, CONTRACT_OPERATIONS, CONTROL_PREFIX, CONTROL_TOKEN_HEADER, CanonicalJsonError, type CanonicalJsonErrorCode, type CanonicalObject, type CanonicalValue, type ClientIdentity, type ClientKind, type ClientProofClock, type ClientProofContext, type ClientProofCredentials, type ClientProofDevHandler, type ClientProofDevHandlerOptions, type ClientProofErrorCode, type ClientProofGuardOptions, type ClientProofInput, ClientProofRefusal, type ClientProofReplayStore, ClientProofState, type ClientProofStateOptions, type ClientProofStats, type ContractItem, type ContractOperation, ContractTypeError, DEFAULT_REPLAY_WINDOW_MILLIS, DEFAULT_SESSION_TTL_MILLIS, DEV_CATALOGUE, DEV_MAX_LIMIT, type EchoRequest, type HandshakeRequest, type ListItemsRequest, MemoryReplayLedger, MemoryReplayStore, PROOF_SIGNATURE_BYTES, PROOF_SIGNATURE_HEX_LENGTH, ProofInputError, RedisReplayStore, SERVER_CONTRACT_HEADERS, TestClock, admitClientProofRequest, applyServerContractHeaders, canonicalProofInput, configureClientProofReplayStore, createClientProofDevHandler, createClientProofGuard, createClientVersionMiddleware, decodeEchoRequest, decodeHandshakeRequest, decodeListItemsRequest, encodeCanonicalJson, encodeEchoResponse, encodeHandshakeResponse, encodeListItemsResponse, getClientProofReplayStore, isAppKind, isCanonicalBytes, isContractVersionSupported, isRequestContentType, judgeClientIdentity, newHexId, parseCanonicalJson, parseClientProofPublicKey, readClientIdentity, readCredentials, replayLedgerKey, serverContractHeaders, sha256Hex, signClientProof, systemClock, verifyClientProof };
|