@wtfalch/auth 0.8.0 → 0.9.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.
- package/dist/auth.js +33 -2
- package/package.json +1 -1
package/dist/auth.js
CHANGED
|
@@ -135,7 +135,12 @@ export function createAuth(input) {
|
|
|
135
135
|
};
|
|
136
136
|
};
|
|
137
137
|
const callback = async (request) => {
|
|
138
|
-
|
|
138
|
+
// Behind a proxy the request can arrive as http:// or on an internal host,
|
|
139
|
+
// and `validCallback` would refuse it. The browser reached this app, so the
|
|
140
|
+
// path and query are what it asked for, on the app's own origin.
|
|
141
|
+
const { pathname, search } = new URL(request.url);
|
|
142
|
+
const callbackUrl = new URL(`${pathname}${search}`, options().appUrl).href;
|
|
143
|
+
const { location, cookies } = await complete(callbackUrl, request.headers.get('cookie'));
|
|
139
144
|
return redirect(location, cookies);
|
|
140
145
|
};
|
|
141
146
|
const logout = async (request) => {
|
|
@@ -503,7 +508,7 @@ export function createAuth(input) {
|
|
|
503
508
|
const device = await requestDeviceAuthorization(options(), scopeFor(options().organizationId));
|
|
504
509
|
const cookie = await sealQrTransaction(options(), { dc: device.deviceCode, iv: device.interval }, device.expiresIn);
|
|
505
510
|
return {
|
|
506
|
-
url: device.verificationUriComplete,
|
|
511
|
+
url: qrVerificationUrl(options(), device.verificationUriComplete),
|
|
507
512
|
userCode: device.userCode,
|
|
508
513
|
expiresIn: device.expiresIn,
|
|
509
514
|
interval: device.interval,
|
|
@@ -694,3 +699,29 @@ function reasonOf(error) {
|
|
|
694
699
|
return 'denied';
|
|
695
700
|
return 'exchange';
|
|
696
701
|
}
|
|
702
|
+
/**
|
|
703
|
+
* The issuer always builds `verification_uri_complete` on itself
|
|
704
|
+
* (`<issuer>/device?user_code=...`). A namespace with its own login host
|
|
705
|
+
* keeps that namespace's users, sessions and passkeys there, so the phone
|
|
706
|
+
* must land on the login host instead -- but only by rewriting a URL that is
|
|
707
|
+
* exactly what the issuer was expected to return; anything else is refused
|
|
708
|
+
* rather than sent somewhere unexpected.
|
|
709
|
+
*/
|
|
710
|
+
function qrVerificationUrl(options, verificationUriComplete) {
|
|
711
|
+
const loginOrigin = options.namespace?.loginOrigin;
|
|
712
|
+
const issuerOrigin = new URL(options.issuer).origin;
|
|
713
|
+
if (!loginOrigin || loginOrigin === issuerOrigin)
|
|
714
|
+
return verificationUriComplete;
|
|
715
|
+
let url;
|
|
716
|
+
try {
|
|
717
|
+
url = new URL(verificationUriComplete);
|
|
718
|
+
}
|
|
719
|
+
catch {
|
|
720
|
+
throw new AuthError('request', 'the issuer returned an unusable device verification URL');
|
|
721
|
+
}
|
|
722
|
+
if (url.origin !== issuerOrigin || url.pathname !== '/device')
|
|
723
|
+
throw new AuthError('request', 'the issuer returned an unexpected device verification URL');
|
|
724
|
+
const rewritten = new URL(`${loginOrigin}/device`);
|
|
725
|
+
rewritten.search = url.search;
|
|
726
|
+
return rewritten.href;
|
|
727
|
+
}
|
package/package.json
CHANGED