@oxyhq/services
Version:
152 lines (144 loc) • 4.73 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useAuth = useAuth;
Object.defineProperty(exports, "useOxy", {
enumerable: true,
get: function () {
return _OxyContext.useOxy;
}
});
var _react = require("react");
var _OxyContext = require("../context/OxyContext.js");
var _useWebSSO = require("./useWebSSO.js");
/**
* Unified Auth Hook
*
* Provides a clean, standard interface for authentication across all platforms.
* This is the recommended way to access auth state in Oxy apps.
*
* Usage:
* ```tsx
* import { useAuth } from '@oxyhq/services';
*
* function MyComponent() {
* const { user, isAuthenticated, isLoading, signIn, signOut } = useAuth();
*
* if (isLoading) return <Loading />;
* if (!isAuthenticated) return <SignInButton onClick={() => signIn()} />;
* return <Welcome user={user} />;
* }
* ```
*
* Cross-domain SSO:
* - Web: Automatic via FedCM (Chrome 108+, Safari 16.4+)
* - Native: Automatic via shared Keychain/Account Manager
* - Manual sign-in: signIn() opens popup (web) or auth sheet (native)
*/
/**
* Unified auth hook for all Oxy apps
*
* Features:
* - Zero config: Just wrap with OxyProvider and use
* - Cross-platform: Same API on native and web
* - Auto SSO: Web apps automatically check for cross-domain sessions
* - Type-safe: Full TypeScript support
*/
function useAuth() {
const {
user,
isAuthenticated,
isLoading,
isTokenReady,
error,
signIn: oxySignIn,
handlePopupSession,
logout,
logoutAll,
refreshSessions,
oxyServices,
hasIdentity,
getPublicKey,
showBottomSheet
} = (0, _OxyContext.useOxy)();
const signIn = (0, _react.useCallback)(async publicKey => {
// Check if we're on the identity provider itself (auth.oxy.so)
// Only auth.oxy.so has local login forms - accounts.oxy.so is a client app
const isIdentityProvider = (0, _useWebSSO.isWebBrowser)() && window.location.hostname === 'auth.oxy.so';
// Web (not on IdP): Use popup-based authentication
// We go straight to popup to preserve the "user gesture" (click event)
// FedCM silent SSO already runs on page load via useWebSSO
// If user is clicking "Sign In", they need interactive auth NOW
if ((0, _useWebSSO.isWebBrowser)() && !publicKey && !isIdentityProvider) {
try {
const popupSession = await oxyServices.signInWithPopup?.();
if (popupSession?.user) {
// Update context state with the session (this updates user, sessions, storage)
await handlePopupSession(popupSession);
return popupSession.user;
}
throw new Error('Sign-in failed. Please try again.');
} catch (popupError) {
if (popupError instanceof Error && popupError.message.includes('blocked')) {
throw new Error('Popup blocked. Please allow popups for this site.');
}
throw popupError;
}
}
// Native: Use cryptographic identity
// If public key provided, use it directly
if (publicKey) {
return oxySignIn(publicKey);
}
// Try to get existing identity
const hasExisting = await hasIdentity();
if (hasExisting) {
const existingKey = await getPublicKey();
if (existingKey) {
return oxySignIn(existingKey);
}
}
// No identity - show auth UI
if (showBottomSheet) {
showBottomSheet('OxyAuth');
// Return a promise that resolves when auth completes
return new Promise((_, reject) => {
reject(new Error('Please complete sign-in in the auth sheet'));
});
}
// Web fallback: navigate to login page on auth domain
if ((0, _useWebSSO.isWebBrowser)()) {
const loginUrl = window.location.hostname.includes('oxy.so') ? '/login' : 'https://accounts.oxy.so/login';
window.location.href = loginUrl;
return new Promise(() => {}); // Never resolves, page will redirect
}
throw new Error('No authentication method available');
}, [oxySignIn, hasIdentity, getPublicKey, showBottomSheet, oxyServices, handlePopupSession]);
const signOut = (0, _react.useCallback)(async () => {
await logout();
}, [logout]);
const signOutAll = (0, _react.useCallback)(async () => {
await logoutAll();
}, [logoutAll]);
const refresh = (0, _react.useCallback)(async () => {
await refreshSessions();
}, [refreshSessions]);
return {
// State
user,
isAuthenticated,
isLoading,
isReady: isTokenReady,
error,
// Actions
signIn,
signOut,
signOutAll,
refresh,
// Advanced
oxyServices
};
}
// Re-export useOxy for backward compatibility and advanced usage
//# sourceMappingURL=useAuth.js.map