@bagelink/auth 1.15.110 → 1.15.114
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/index.cjs +21 -0
- package/dist/index.mjs +21 -0
- package/dist/sso.d.ts +24 -0
- package/package.json +1 -1
- package/src/sso.ts +53 -0
package/dist/index.cjs
CHANGED
|
@@ -892,6 +892,26 @@ function getAllSSOProviders() {
|
|
|
892
892
|
function isSupportedProvider(provider) {
|
|
893
893
|
return provider in ssoProviders;
|
|
894
894
|
}
|
|
895
|
+
function handleSsoPopup() {
|
|
896
|
+
if (typeof window === "undefined" || !window.opener || window.opener === window) {
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
const { code, state, error } = queryParams();
|
|
900
|
+
if (!code && !error) return false;
|
|
901
|
+
const provider = state && typeof sessionStorage !== "undefined" ? sessionStorage.getItem(`oauth_provider:${state}`) ?? void 0 : void 0;
|
|
902
|
+
try {
|
|
903
|
+
window.opener.postMessage(
|
|
904
|
+
{ type: "auth:complete", provider, code: code || void 0, state, error: error || void 0 },
|
|
905
|
+
window.location.origin
|
|
906
|
+
);
|
|
907
|
+
} catch {
|
|
908
|
+
}
|
|
909
|
+
try {
|
|
910
|
+
window.close();
|
|
911
|
+
} catch {
|
|
912
|
+
}
|
|
913
|
+
return true;
|
|
914
|
+
}
|
|
895
915
|
function handleOAuthCallback() {
|
|
896
916
|
const { code, state } = queryParams();
|
|
897
917
|
if (!code || !state) {
|
|
@@ -1618,6 +1638,7 @@ exports.getAllSSOProviders = getAllSSOProviders;
|
|
|
1618
1638
|
exports.getRedirectConfig = getRedirectConfig;
|
|
1619
1639
|
exports.getRedirectUrl = getRedirectUrl;
|
|
1620
1640
|
exports.getSSOProvider = getSSOProvider;
|
|
1641
|
+
exports.handleSsoPopup = handleSsoPopup;
|
|
1621
1642
|
exports.isSupportedProvider = isSupportedProvider;
|
|
1622
1643
|
exports.isValidRedirect = isValidRedirect;
|
|
1623
1644
|
exports.normalizeRedirectConfig = normalizeRedirectConfig;
|
package/dist/index.mjs
CHANGED
|
@@ -890,6 +890,26 @@ function getAllSSOProviders() {
|
|
|
890
890
|
function isSupportedProvider(provider) {
|
|
891
891
|
return provider in ssoProviders;
|
|
892
892
|
}
|
|
893
|
+
function handleSsoPopup() {
|
|
894
|
+
if (typeof window === "undefined" || !window.opener || window.opener === window) {
|
|
895
|
+
return false;
|
|
896
|
+
}
|
|
897
|
+
const { code, state, error } = queryParams();
|
|
898
|
+
if (!code && !error) return false;
|
|
899
|
+
const provider = state && typeof sessionStorage !== "undefined" ? sessionStorage.getItem(`oauth_provider:${state}`) ?? void 0 : void 0;
|
|
900
|
+
try {
|
|
901
|
+
window.opener.postMessage(
|
|
902
|
+
{ type: "auth:complete", provider, code: code || void 0, state, error: error || void 0 },
|
|
903
|
+
window.location.origin
|
|
904
|
+
);
|
|
905
|
+
} catch {
|
|
906
|
+
}
|
|
907
|
+
try {
|
|
908
|
+
window.close();
|
|
909
|
+
} catch {
|
|
910
|
+
}
|
|
911
|
+
return true;
|
|
912
|
+
}
|
|
893
913
|
function handleOAuthCallback() {
|
|
894
914
|
const { code, state } = queryParams();
|
|
895
915
|
if (!code || !state) {
|
|
@@ -1617,6 +1637,7 @@ export {
|
|
|
1617
1637
|
getRedirectConfig,
|
|
1618
1638
|
getRedirectUrl,
|
|
1619
1639
|
getSSOProvider,
|
|
1640
|
+
handleSsoPopup,
|
|
1620
1641
|
isSupportedProvider,
|
|
1621
1642
|
isValidRedirect,
|
|
1622
1643
|
normalizeRedirectConfig,
|
package/dist/sso.d.ts
CHANGED
|
@@ -143,3 +143,27 @@ export declare function getAllSSOProviders(): readonly SSOProviderInstance[];
|
|
|
143
143
|
* Check if a provider is supported
|
|
144
144
|
*/
|
|
145
145
|
export declare function isSupportedProvider(provider: string): provider is SSOProvider;
|
|
146
|
+
/**
|
|
147
|
+
* Popup-mode OAuth landing handler.
|
|
148
|
+
*
|
|
149
|
+
* Call this **once at app startup, before the router mounts**. When the current
|
|
150
|
+
* page was opened as an OAuth popup (it has `?code`/`?state` — or `?error` — and
|
|
151
|
+
* a `window.opener`), it posts an `auth:complete` message back to the opener
|
|
152
|
+
* (which `sso.<provider>.popup()` is waiting for) and closes the popup.
|
|
153
|
+
*
|
|
154
|
+
* This lets a host app support popup SSO **without** a dedicated `/auth/callback`
|
|
155
|
+
* route or component — the whole flow stays on the original page.
|
|
156
|
+
*
|
|
157
|
+
* @returns `true` if it handled a popup callback (caller should stop bootstrapping
|
|
158
|
+
* the app — the window is closing), otherwise `false`.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* import { handleSsoPopup } from '@bagelink/auth'
|
|
163
|
+
* if (handleSsoPopup()) { // we're the popup; do nothing else
|
|
164
|
+
* } else {
|
|
165
|
+
* app.mount('#app')
|
|
166
|
+
* }
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export declare function handleSsoPopup(): boolean;
|
package/package.json
CHANGED
package/src/sso.ts
CHANGED
|
@@ -623,6 +623,59 @@ export function isSupportedProvider(provider: string): provider is SSOProvider {
|
|
|
623
623
|
return provider in ssoProviders
|
|
624
624
|
}
|
|
625
625
|
|
|
626
|
+
/**
|
|
627
|
+
* Popup-mode OAuth landing handler.
|
|
628
|
+
*
|
|
629
|
+
* Call this **once at app startup, before the router mounts**. When the current
|
|
630
|
+
* page was opened as an OAuth popup (it has `?code`/`?state` — or `?error` — and
|
|
631
|
+
* a `window.opener`), it posts an `auth:complete` message back to the opener
|
|
632
|
+
* (which `sso.<provider>.popup()` is waiting for) and closes the popup.
|
|
633
|
+
*
|
|
634
|
+
* This lets a host app support popup SSO **without** a dedicated `/auth/callback`
|
|
635
|
+
* route or component — the whole flow stays on the original page.
|
|
636
|
+
*
|
|
637
|
+
* @returns `true` if it handled a popup callback (caller should stop bootstrapping
|
|
638
|
+
* the app — the window is closing), otherwise `false`.
|
|
639
|
+
*
|
|
640
|
+
* @example
|
|
641
|
+
* ```ts
|
|
642
|
+
* import { handleSsoPopup } from '@bagelink/auth'
|
|
643
|
+
* if (handleSsoPopup()) { // we're the popup; do nothing else
|
|
644
|
+
* } else {
|
|
645
|
+
* app.mount('#app')
|
|
646
|
+
* }
|
|
647
|
+
* ```
|
|
648
|
+
*/
|
|
649
|
+
export function handleSsoPopup(): boolean {
|
|
650
|
+
if (typeof window === 'undefined' || !window.opener || window.opener === window) {
|
|
651
|
+
return false
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
const { code, state, error } = queryParams()
|
|
655
|
+
if (!code && !error) return false
|
|
656
|
+
|
|
657
|
+
const provider = state && typeof sessionStorage !== 'undefined'
|
|
658
|
+
? sessionStorage.getItem(`oauth_provider:${state}`) ?? undefined
|
|
659
|
+
: undefined
|
|
660
|
+
|
|
661
|
+
try {
|
|
662
|
+
window.opener.postMessage(
|
|
663
|
+
{ type: 'auth:complete', provider, code: code || undefined, state, error: error || undefined },
|
|
664
|
+
window.location.origin,
|
|
665
|
+
)
|
|
666
|
+
} catch {
|
|
667
|
+
// Opener gone or cross-origin — the opener's polling fallback still works.
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// Close the popup; the opener resolves via the message (or its poll).
|
|
671
|
+
try {
|
|
672
|
+
window.close()
|
|
673
|
+
} catch {
|
|
674
|
+
/* ignore */
|
|
675
|
+
}
|
|
676
|
+
return true
|
|
677
|
+
}
|
|
678
|
+
|
|
626
679
|
/**
|
|
627
680
|
* Handle OAuth callback from URL
|
|
628
681
|
* Internal helper - use sso.handleCallback() instead
|