@spfn/auth 0.3.0-beta.25 → 0.3.0-beta.27
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 +49 -7
- package/dist/client-proof.js +3 -2
- package/dist/client-proof.js.map +1 -1
- package/dist/index.d.ts +194 -189
- package/dist/index.js +40 -40
- package/dist/index.js.map +1 -1
- package/dist/{machine-principals-CdEgxOB1.d.ts → machine-principals-BvRw8b8t.d.ts} +18 -0
- package/dist/nextjs/api.js +16 -13
- package/dist/nextjs/api.js.map +1 -1
- package/dist/server.d.ts +37 -4
- package/dist/server.js +210 -33
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -591,6 +591,12 @@ declare function completePasswordResetService(params: CompletePasswordResetParam
|
|
|
591
591
|
* refuses the account's live records too, as `denied`, so they land in that row
|
|
592
592
|
* of the table. See `denyAllActiveByUserId`; the three callers are the three
|
|
593
593
|
* places that revoke every key at once.
|
|
594
|
+
*
|
|
595
|
+
* A poll may ask to wait (`waitMillis`). `waitForDeviceAuthAnswerService` then
|
|
596
|
+
* holds a pending record's request — before the route's transaction opens — until
|
|
597
|
+
* something answers it, the wait runs out, or the device hangs up, and only after
|
|
598
|
+
* that is the table above applied. A long poll answers exactly what a short poll
|
|
599
|
+
* sent at the same moment would, only sooner.
|
|
594
600
|
*/
|
|
595
601
|
|
|
596
602
|
interface StartDeviceAuthParams {
|
|
@@ -645,10 +651,21 @@ interface PollDeviceAuthParams {
|
|
|
645
651
|
* to run a WebAuthn ceremony in needs.
|
|
646
652
|
*/
|
|
647
653
|
webProxy?: boolean;
|
|
654
|
+
/**
|
|
655
|
+
* How long this request already waited on the server, from the long-poll
|
|
656
|
+
* middleware. A pending answer subtracts it from the interval: the device
|
|
657
|
+
* has done that much of its waiting here.
|
|
658
|
+
*/
|
|
659
|
+
waitedMillis?: number;
|
|
648
660
|
}
|
|
649
661
|
/** Nobody has answered yet. Not an error — the waiting device waits. */
|
|
650
662
|
interface DeviceAuthPendingResult {
|
|
651
663
|
status: 'pending';
|
|
664
|
+
/**
|
|
665
|
+
* How long to wait before polling again, less what the request already
|
|
666
|
+
* waited on the server — 0 once a long poll has waited at least the interval,
|
|
667
|
+
* so the device asks again at once.
|
|
668
|
+
*/
|
|
652
669
|
intervalMillis: number;
|
|
653
670
|
}
|
|
654
671
|
/**
|
|
@@ -3341,6 +3358,7 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
|
|
|
3341
3358
|
pollDeviceAuth: _spfn_core_route.RouteDef<{
|
|
3342
3359
|
body: _sinclair_typebox.TObject<{
|
|
3343
3360
|
deviceCode: _sinclair_typebox.TString;
|
|
3361
|
+
waitMillis: _sinclair_typebox.TOptional<_sinclair_typebox.TInteger>;
|
|
3344
3362
|
}>;
|
|
3345
3363
|
}, {}, {
|
|
3346
3364
|
status: "pending";
|
package/dist/nextjs/api.js
CHANGED
|
@@ -577,9 +577,9 @@ var loginRegisterInterceptor = {
|
|
|
577
577
|
ctx.body.oldKeyId = oldKeyId;
|
|
578
578
|
}
|
|
579
579
|
delete ctx.body.remember;
|
|
580
|
-
ctx.metadata.
|
|
581
|
-
ctx.metadata.
|
|
582
|
-
ctx.metadata.
|
|
580
|
+
ctx.metadata.newPrivateKey = keyPair.privateKey;
|
|
581
|
+
ctx.metadata.newKeyId = keyPair.keyId;
|
|
582
|
+
ctx.metadata.newAlgorithm = keyPair.algorithm;
|
|
583
583
|
ctx.metadata.remember = remember;
|
|
584
584
|
await next();
|
|
585
585
|
},
|
|
@@ -598,9 +598,9 @@ var loginRegisterInterceptor = {
|
|
|
598
598
|
const ttl = getSessionTtl(ctx.metadata.remember);
|
|
599
599
|
const sessionData = {
|
|
600
600
|
userId: userData.userId,
|
|
601
|
-
privateKey: ctx.metadata.
|
|
602
|
-
keyId: ctx.metadata.
|
|
603
|
-
algorithm: ctx.metadata.
|
|
601
|
+
privateKey: ctx.metadata.newPrivateKey,
|
|
602
|
+
keyId: ctx.metadata.newKeyId,
|
|
603
|
+
algorithm: ctx.metadata.newAlgorithm,
|
|
604
604
|
...bindingSessionFields(userData, ctx.request.headers["user-agent"])
|
|
605
605
|
};
|
|
606
606
|
const sealed = await sealSession(sessionData, ttl);
|
|
@@ -617,7 +617,7 @@ var loginRegisterInterceptor = {
|
|
|
617
617
|
});
|
|
618
618
|
ctx.setCookies.push({
|
|
619
619
|
name: COOKIE_NAMES.SESSION_KEY_ID,
|
|
620
|
-
value: ctx.metadata.
|
|
620
|
+
value: ctx.metadata.newKeyId,
|
|
621
621
|
options: {
|
|
622
622
|
httpOnly: true,
|
|
623
623
|
secure: cookieSecure,
|
|
@@ -626,7 +626,7 @@ var loginRegisterInterceptor = {
|
|
|
626
626
|
path: "/"
|
|
627
627
|
}
|
|
628
628
|
});
|
|
629
|
-
await pushCsrfCookie(ctx.setCookies, ctx.metadata.
|
|
629
|
+
await pushCsrfCookie(ctx.setCookies, ctx.metadata.newKeyId, ttl);
|
|
630
630
|
} catch (error) {
|
|
631
631
|
const err = error;
|
|
632
632
|
authLogger.interceptor.login.error("Failed to save session", err);
|
|
@@ -693,11 +693,11 @@ function challengeSecretOf(body) {
|
|
|
693
693
|
return typeof secret === "string" ? secret : void 0;
|
|
694
694
|
}
|
|
695
695
|
async function pendingKeyFor(ctx) {
|
|
696
|
-
if (ctx.metadata.
|
|
696
|
+
if (ctx.metadata.newPrivateKey && ctx.metadata.newKeyId) {
|
|
697
697
|
return {
|
|
698
|
-
privateKey: ctx.metadata.
|
|
699
|
-
keyId: ctx.metadata.
|
|
700
|
-
algorithm: ctx.metadata.
|
|
698
|
+
privateKey: ctx.metadata.newPrivateKey,
|
|
699
|
+
keyId: ctx.metadata.newKeyId,
|
|
700
|
+
algorithm: ctx.metadata.newAlgorithm
|
|
701
701
|
};
|
|
702
702
|
}
|
|
703
703
|
const oauthPending = ctx.cookies.get(COOKIE_NAMES.OAUTH_PENDING);
|
|
@@ -825,6 +825,9 @@ function refuseAsContextChanged(ctx) {
|
|
|
825
825
|
function isKeyExpiredRefusal(body) {
|
|
826
826
|
return body?.__type === "KeyExpiredError";
|
|
827
827
|
}
|
|
828
|
+
function sessionQueued(setCookies) {
|
|
829
|
+
return setCookies.some((cookie) => cookie.name === COOKIE_NAMES.SESSION);
|
|
830
|
+
}
|
|
828
831
|
var generalAuthInterceptor = {
|
|
829
832
|
pathPattern: "*",
|
|
830
833
|
// Match all paths, filter by requiresAuth()
|
|
@@ -953,7 +956,7 @@ var generalAuthInterceptor = {
|
|
|
953
956
|
}
|
|
954
957
|
});
|
|
955
958
|
pushCsrfCookieRemoval(ctx.setCookies);
|
|
956
|
-
} else if (ctx.metadata.refreshSession && ctx.response.status === 200) {
|
|
959
|
+
} else if (ctx.metadata.refreshSession && ctx.response.status === 200 && !sessionQueued(ctx.setCookies)) {
|
|
957
960
|
try {
|
|
958
961
|
const sessionData = ctx.metadata.sessionData;
|
|
959
962
|
const ttl = getSessionTtl();
|