@opble/auth0-react 1.1.5 → 1.1.7
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/components/AccessForbidden.js +6 -0
- package/dist/components/AuthClearing.js +20 -0
- package/dist/components/AuthError.js +7 -0
- package/dist/components/AuthLoading.js +4 -0
- package/dist/components/ProtectedRoute.js +79 -0
- package/dist/components/Unauthorized.js +7 -0
- package/dist/helpers/jwt.js +27 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -7784
- package/dist/slices/auth.js +19 -0
- package/dist/slices/selectors.js +3 -0
- package/dist/slices/types.js +1 -0
- package/dist/style.css +853 -0
- package/dist/util/rtk.js +21 -0
- package/package.json +6 -7
- package/dist/index.css +0 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth0 } from '@auth0/auth0-react';
|
|
3
|
+
export function AccessForbidden({ homeUrl = '/', supportEmail, supportUrl, } = {}) {
|
|
4
|
+
const { logout } = useAuth0();
|
|
5
|
+
return (_jsx("div", { className: "obar:min-h-screen obar:flex obar:items-center obar:justify-center obar:bg-linear-to-b obar:from-white obar:to-gray-100 obar:dark:from-slate-900 obar:dark:to-slate-800 obar:transition-colors obar:px-4", children: _jsxs("div", { className: "obar:w-full obar:max-w-lg obar:p-8 obar:rounded-2xl obar:shadow-xl obar:border obar:border-gray-100 obar:dark:border-slate-700 obar:bg-white/70 obar:dark:bg-slate-900/60 obar:backdrop-blur-sm", children: [_jsxs("div", { className: "obar:flex obar:flex-col obar:items-center obar:text-center", children: [_jsx("div", { className: "obar:shrink-0 obar:h-16 obar:w-16 obar:rounded-full obar:bg-red-100 obar:dark:bg-red-900/20 obar:flex obar:items-center obar:justify-center obar:mb-4", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-8 obar:w-8 obar:text-red-600 obar:dark:text-red-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), _jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }) }), _jsx("h1", { className: "obar:text-3xl obar:font-bold obar:text-slate-900 obar:dark:text-slate-100 obar:mb-2", children: "Access Forbidden" }), _jsx("p", { className: "obar:text-base obar:text-slate-600 obar:dark:text-slate-300 obar:mb-6", children: "You don't have permission to access this page. Please contact your administrator if you believe this is an error." }), _jsxs("div", { className: "obar:inline-flex obar:items-center obar:gap-2 obar:px-4 obar:py-2 obar:rounded-full obar:bg-red-50 obar:dark:bg-red-900/10 obar:border obar:border-red-200 obar:dark:border-red-800 obar:mb-8", children: [_jsx("svg", { className: "obar:h-4 obar:w-4 obar:text-red-600 obar:dark:text-red-400", fill: "currentColor", viewBox: "0 0 20 20", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", clipRule: "evenodd" }) }), _jsx("span", { className: "obar:text-sm obar:font-medium obar:text-red-700 obar:dark:text-red-300", children: "Error 403" })] }), _jsxs("div", { className: "obar:flex obar:flex-col obar:gap-4 obar:w-full", children: [_jsxs("div", { className: "obar:flex obar:flex-col obar:sm:flex-row obar:gap-3", children: [_jsxs("button", { onClick: () => (window.location.href = homeUrl), className: "obar:flex-1 obar:px-6 obar:py-3 obar:rounded-lg obar:bg-indigo-600 obar:hover:bg-indigo-700 obar:text-white obar:font-medium obar:transition-colors obar:shadow-lg obar:shadow-indigo-500/20 obar:cursor-pointer obar:flex obar:items-center obar:justify-center obar:gap-2", children: [_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-5 obar:w-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), _jsx("polyline", { points: "9 22 9 12 15 12 15 22" })] }), "Go to Home"] }), _jsxs("button", { onClick: () => logout(), className: "obar:flex-1 obar:px-6 obar:py-3 obar:rounded-lg obar:bg-red-600 obar:hover:bg-red-700 obar:dark:bg-red-700/80 obar:dark:hover:bg-red-700 obar:text-white obar:font-medium obar:transition-colors obar:shadow-lg obar:shadow-red-500/20 obar:dark:shadow-red-900/30 obar:cursor-pointer obar:flex obar:items-center obar:justify-center obar:gap-2", children: ["Sign Out", _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-5 obar:w-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }), _jsx("polyline", { points: "16 17 21 12 16 7" }), _jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })] })] })] }), _jsx("button", { onClick: () => window.history.back(), className: "obar:text-sm obar:text-slate-500 obar:hover:text-slate-700 obar:dark:text-slate-400 obar:dark:hover:text-slate-200 obar:underline obar:underline-offset-4 obar:transition-colors obar:cursor-pointer", children: "\u2190 Go back to previous page" })] })] }), (supportEmail || supportUrl) && (_jsx("div", { className: "obar:mt-8 obar:pt-6 obar:border-t obar:border-slate-200 obar:dark:border-slate-700", children: _jsxs("p", { className: "obar:text-sm obar:text-slate-500 obar:dark:text-slate-400 obar:text-center", children: ["Need help?", ' ', _jsx("a", { href: supportUrl || `mailto:${supportEmail}`, className: "obar:text-indigo-600 obar:dark:text-indigo-400 obar:hover:underline obar:font-medium obar:cursor-pointer", children: "Contact support" })] }) }))] }) }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function AuthClearing() {
|
|
3
|
+
return (_jsxs("div", { className: "obar:min-h-screen obar:flex obar:items-center obar:justify-center obar:bg-linear-to-b obar:from-white obar:to-gray-100 obar:dark:from-slate-900 obar:dark:to-slate-800 obar:transition-colors", children: [_jsx("div", { className: "obar:w-full obar:max-w-lg obar:p-8 obar:rounded-2xl obar:shadow-xl obar:border obar:border-gray-100 obar:dark:border-slate-700 obar:bg-white/70 obar:dark:bg-slate-900/60 obar:backdrop-blur-sm", children: _jsxs("div", { className: "obar:flex obar:flex-col obar:items-center obar:text-center", children: [_jsxs("div", { className: "obar:relative obar:mb-6", children: [_jsx("div", { className: "obar:shrink-0 obar:h-16 obar:w-16 obar:rounded-full obar:bg-indigo-100 obar:dark:bg-indigo-900/20 obar:flex obar:items-center obar:justify-center", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-8 obar:w-8 obar:text-indigo-600 obar:dark:text-indigo-400 obar:animate-pulse", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }), _jsx("polyline", { points: "16 17 21 12 16 7" }), _jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })] }) }), _jsx("div", { className: "obar:absolute obar:inset-0 obar:rounded-full obar:bg-indigo-400/30 obar:dark:bg-indigo-600/20 obar:animate-ping" })] }), _jsx("h1", { className: "obar:text-2xl obar:font-bold obar:text-slate-900 obar:dark:text-slate-100 obar:mb-2", children: "Signing You Out" }), _jsx("p", { className: "obar:text-base obar:text-slate-600 obar:dark:text-slate-300 obar:mb-6", children: "Please wait while we securely clear your session..." }), _jsx("div", { className: "obar:w-full obar:max-w-xs", children: _jsx("div", { className: "obar:h-1.5 obar:bg-slate-200 obar:dark:bg-slate-700 obar:rounded-full obar:overflow-hidden", children: _jsx("div", { className: "obar:h-full obar:bg-indigo-600 obar:dark:bg-indigo-500 obar:rounded-full animate-progress" }) }) }), _jsx("p", { className: "obar:mt-6 obar:text-sm obar:text-slate-500 obar:dark:text-slate-400", children: "You'll be redirected shortly" })] }) }), _jsx("style", { children: `
|
|
4
|
+
@keyframes progress {
|
|
5
|
+
0% {
|
|
6
|
+
width: 0%;
|
|
7
|
+
transform: translateX(0);
|
|
8
|
+
}
|
|
9
|
+
50% {
|
|
10
|
+
width: 70%;
|
|
11
|
+
}
|
|
12
|
+
100% {
|
|
13
|
+
width: 100%;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
.animate-progress {
|
|
17
|
+
animation: progress 1.5s ease-in-out infinite;
|
|
18
|
+
}
|
|
19
|
+
` })] }));
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth0 } from '@auth0/auth0-react';
|
|
3
|
+
export function AuthError({ homeUrl = '/', supportEmail, supportUrl, error = null, } = {}) {
|
|
4
|
+
const { loginWithRedirect } = useAuth0();
|
|
5
|
+
return (_jsx("div", { className: "obar:min-h-screen obar:flex obar:items-center obar:justify-center obar:bg-linear-to-b obar:from-white obar:to-gray-100 obar:dark:from-slate-900 obar:dark:to-slate-800 obar:transition-colors obar:px-4", children: _jsxs("div", { className: "obar:w-full obar:max-w-lg obar:p-8 obar:rounded-2xl obar:shadow-xl obar:border obar:border-gray-100 obar:dark:border-slate-700 obar:bg-white/70 obar:dark:bg-slate-900/60 obar:backdrop-blur-sm", children: [_jsxs("div", { className: "obar:flex obar:flex-col obar:items-center obar:text-center", children: [_jsx("div", { className: "obar:shrink-0 obar:h-16 obar:w-16 obar:rounded-full obar:bg-red-50 obar:dark:bg-red-900/10 obar:flex obar:items-center obar:justify-center obar:mb-4", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-8 obar:w-8 obar:text-red-600 obar:dark:text-red-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("path", { d: "M12 8v4" }), _jsx("path", { d: "M12 16h.01" })] }) }), _jsx("h1", { className: "obar:text-3xl obar:font-bold obar:text-slate-900 obar:dark:text-slate-100 obar:mb-2", children: "Authentication Error" }), _jsx("p", { className: "obar:text-base obar:text-slate-600 obar:dark:text-slate-300 obar:mb-6", children: "Authentication failed. Sign out and sign back in to resolve transient errors, or return home." }), error && (_jsx("div", { className: "obar:mb-4 obar:w-full obar:px-4 obar:py-3 obar:rounded-md obar:bg-red-50 obar:dark:bg-red-900/10 obar:border obar:border-red-100 obar:dark:border-red-800 obar:text-sm obar:text-red-700 obar:dark:text-red-200", children: typeof error === 'string' ? error : error.message })), _jsxs("div", { className: "obar:flex obar:flex-col obar:gap-4 obar:w-full", children: [_jsxs("div", { className: "obar:flex obar:flex-col obar:sm:flex-row obar:gap-3", children: [_jsxs("button", { onClick: () => (window.location.href = homeUrl), className: "obar:flex-1 obar:px-6 obar:py-3 obar:rounded-lg obar:bg-transparent obar:border obar:border-gray-200 obar:dark:border-white/5 obar:text-slate-700 obar:dark:text-slate-200 obar:hover:bg-gray-50 obar:dark:hover:bg-slate-800 obar:font-medium obar:transition-colors obar:shadow-sm obar:cursor-pointer obar:flex obar:items-center obar:justify-center obar:gap-2", children: [_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-5 obar:w-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), _jsx("polyline", { points: "9 22 9 12 15 12 15 22" })] }), "Go to Home"] }), _jsxs("button", { onClick: () => loginWithRedirect(), className: "obar:flex-1 obar:px-6 obar:py-3 obar:rounded-lg obar:bg-indigo-600 obar:hover:bg-indigo-700 obar:text-white obar:font-medium obar:transition-colors obar:shadow-lg obar:shadow-indigo-500/20 obar:dark:bg-indigo-500 obar:dark:hover:bg-indigo-600 obar:cursor-pointer obar:flex obar:items-center obar:justify-center obar:gap-2", children: ["Sign In", _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-5 obar:w-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" }), _jsx("polyline", { points: "10 17 15 12 10 7" }), _jsx("line", { x1: "15", y1: "12", x2: "3", y2: "12" })] })] })] }), _jsx("button", { onClick: () => window.history.back(), className: "obar:text-sm obar:text-slate-500 obar:hover:text-slate-700 obar:dark:text-slate-400 obar:dark:hover:text-slate-200 obar:underline obar:underline-offset-4 obar:transition-colors obar:cursor-pointer", children: "\u2190 Go back to previous page" })] })] }), (supportEmail || supportUrl) && (_jsx("div", { className: "obar:mt-8 obar:pt-6 obar:border-t obar:border-slate-200 obar:dark:border-slate-700", children: _jsxs("p", { className: "obar:text-sm obar:text-slate-500 obar:dark:text-slate-400 obar:text-center", children: ["Need help?", ' ', _jsx("a", { href: supportUrl || `mailto:${supportEmail}`, className: "obar:text-indigo-600 obar:dark:text-indigo-400 obar:hover:underline obar:font-medium obar:cursor-pointer", children: "Contact support" })] }) }))] }) }));
|
|
6
|
+
}
|
|
7
|
+
export default AuthError;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function AuthLoading() {
|
|
3
|
+
return (_jsxs("div", { className: "obar:min-h-screen obar:flex obar:items-center obar:justify-center obar:bg-linear-to-b obar:from-white obar:to-gray-100 obar:dark:from-slate-900 obar:dark:to-slate-800 obar:transition-colors", children: [_jsxs("div", { className: "obar:w-full obar:max-w-lg obar:p-8 obar:rounded-2xl obar:shadow-xl obar:border obar:border-gray-100 obar:dark:border-slate-700 obar:bg-white/70 obar:dark:bg-slate-900/60 obar:backdrop-blur-sm", children: [_jsxs("div", { className: "obar:flex obar:items-center obar:gap-4", children: [_jsx("div", { className: "obar:shrink-0 obar:h-14 obar:w-14 obar:rounded-lg obar:bg-indigo-600 obar:flex obar:items-center obar:justify-center obar:text-white", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-7 obar:w-7", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [_jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 2v10l3-3" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 12v7a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-7" })] }) }), _jsxs("div", { children: [_jsx("h2", { className: "obar:text-lg obar:font-semibold obar:text-slate-900 obar:dark:text-slate-100", children: "Signing you in" }), _jsx("p", { className: "obar:mt-1 obar:text-sm obar:text-slate-600 obar:dark:text-slate-300", children: "Hang tight \u2014 we're securely authenticating your account." })] })] }), _jsxs("div", { className: "obar:mt-8 obar:flex obar:flex-col obar:items-center", children: [_jsxs("div", { className: "obar:flex obar:items-center obar:gap-3", children: [_jsxs("svg", { className: "obar:h-8 obar:w-8 obar:text-indigo-600 obar:animate-spin", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": true, children: [_jsx("circle", { className: "obar:opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "obar:opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" })] }), _jsx("span", { className: "obar:text-sm obar:text-slate-700 obar:dark:text-slate-200", children: "Authenticating\u2026" })] }), _jsx("p", { className: "obar:mt-4 obar:text-xs obar:text-slate-500 obar:dark:text-slate-400 obar:text-center", children: "If this takes longer than a few seconds, try refreshing the page or checking your network connection." })] })] }), _jsx("div", { className: "obar:absolute obar:bottom-6 obar:text-xs obar:text-slate-500 obar:dark:text-slate-400", children: "opble \u2022 secure authentication" })] }));
|
|
4
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth0 } from '@auth0/auth0-react';
|
|
3
|
+
import { SerializableUserFactory } from '@opble/entity-auth';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
6
|
+
import { decodeJWT } from '../helpers/jwt';
|
|
7
|
+
import { setAccessToken, setUser } from '../slices/auth';
|
|
8
|
+
import { selectAccessToken, selectUser } from '../slices/selectors';
|
|
9
|
+
import { AccessForbidden } from './AccessForbidden';
|
|
10
|
+
import AuthError from './AuthError';
|
|
11
|
+
import { AuthLoading } from './AuthLoading';
|
|
12
|
+
import { Unauthorized } from './Unauthorized';
|
|
13
|
+
/**
|
|
14
|
+
* Component to protect routes that require authentication.
|
|
15
|
+
*
|
|
16
|
+
* Usage in route configuration:
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <Route
|
|
19
|
+
* path="/dashboard"
|
|
20
|
+
* element={
|
|
21
|
+
* <ProtectedRoute>
|
|
22
|
+
* <Dashboard />
|
|
23
|
+
* </ProtectedRoute>
|
|
24
|
+
* }
|
|
25
|
+
* />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function ProtectedRoute({ children, requiredPermissions, }) {
|
|
29
|
+
const dispatch = useDispatch();
|
|
30
|
+
const accessToken = useSelector(selectAccessToken);
|
|
31
|
+
const user = useSelector(selectUser);
|
|
32
|
+
const { isAuthenticated, isLoading, getAccessTokenSilently, getIdTokenClaims, } = useAuth0();
|
|
33
|
+
const [error, setError] = useState(null);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const loadAuthData = async () => {
|
|
36
|
+
if (isAuthenticated) {
|
|
37
|
+
try {
|
|
38
|
+
const idToken = await getIdTokenClaims();
|
|
39
|
+
const token = await getAccessTokenSilently();
|
|
40
|
+
const payload = decodeJWT(token);
|
|
41
|
+
if (payload && idToken) {
|
|
42
|
+
dispatch(setUser(SerializableUserFactory.create({
|
|
43
|
+
id: idToken.sub,
|
|
44
|
+
email: idToken.email,
|
|
45
|
+
name: idToken.name,
|
|
46
|
+
emailVerified: idToken.email_verified,
|
|
47
|
+
permissions: payload['permissions'] || [],
|
|
48
|
+
})));
|
|
49
|
+
}
|
|
50
|
+
dispatch(setAccessToken(token));
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
console.error('Failed to get access token silently:', e);
|
|
54
|
+
setError('Failed to get access token silently.');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
loadAuthData();
|
|
59
|
+
}, [isAuthenticated, getAccessTokenSilently, getIdTokenClaims, dispatch]);
|
|
60
|
+
if (isLoading) {
|
|
61
|
+
return _jsx(AuthLoading, {});
|
|
62
|
+
}
|
|
63
|
+
else if (error) {
|
|
64
|
+
return _jsx(AuthError, { error: error });
|
|
65
|
+
}
|
|
66
|
+
else if (!isAuthenticated) {
|
|
67
|
+
return _jsx(Unauthorized, {});
|
|
68
|
+
}
|
|
69
|
+
else if (!accessToken) {
|
|
70
|
+
return _jsx(AuthLoading, {});
|
|
71
|
+
}
|
|
72
|
+
else if (requiredPermissions && user) {
|
|
73
|
+
const hasAllPermissions = requiredPermissions.every((perm) => user.permissions.includes(perm));
|
|
74
|
+
if (!hasAllPermissions) {
|
|
75
|
+
return _jsx(AccessForbidden, {});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return _jsx(_Fragment, { children: children });
|
|
79
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth0 } from '@auth0/auth0-react';
|
|
3
|
+
export function Unauthorized({ homeUrl = '/', supportEmail, supportUrl, } = {}) {
|
|
4
|
+
const { loginWithRedirect } = useAuth0();
|
|
5
|
+
return (_jsx("div", { className: "obar:min-h-screen obar:flex obar:items-center obar:justify-center obar:bg-linear-to-b obar:from-white obar:to-gray-100 obar:dark:from-slate-900 obar:dark:to-slate-800 obar:transition-colors obar:px-4", children: _jsxs("div", { className: "obar:w-full obar:max-w-lg obar:p-8 obar:rounded-2xl obar:shadow-xl obar:border obar:border-gray-100 obar:dark:border-slate-700 obar:bg-white/70 obar:dark:bg-slate-900/60 obar:backdrop-blur-sm", children: [_jsxs("div", { className: "obar:flex obar:flex-col obar:items-center obar:text-center", children: [_jsx("div", { className: "obar:shrink-0 obar:h-16 obar:w-16 obar:rounded-full obar:bg-yellow-50 obar:dark:bg-yellow-900/10 obar:flex obar:items-center obar:justify-center obar:mb-4", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-8 obar:w-8 obar:text-yellow-600 obar:dark:text-yellow-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M12 2l7 4v6c0 5-3.6 9.7-7 11-3.4-1.3-7-6-7-11V6l7-4z" }), _jsx("path", { d: "M9.5 11.5l1.5 1.5 3-3" })] }) }), _jsx("h1", { className: "obar:text-3xl obar:font-bold obar:text-slate-900 obar:dark:text-slate-100 obar:mb-2", children: "Unauthorized" }), _jsx("p", { className: "obar:text-base obar:text-slate-600 obar:dark:text-slate-300 obar:mb-6", children: "You need to sign in to access this page. Please sign in with your account or return home." }), _jsxs("div", { className: "obar:flex obar:flex-col obar:gap-4 obar:w-full", children: [_jsxs("div", { className: "obar:flex obar:flex-col obar:sm:flex-row obar:gap-3", children: [_jsxs("button", { onClick: () => (window.location.href = homeUrl), className: "obar:flex-1 obar:px-6 obar:py-3 obar:rounded-lg obar:bg-transparent obar:border obar:border-gray-200 obar:dark:border-white/5 obar:text-slate-700 obar:dark:text-slate-200 obar:hover:bg-gray-50 obar:dark:hover:bg-slate-800 obar:font-medium obar:transition-colors obar:shadow-sm obar:cursor-pointer obar:flex obar:items-center obar:justify-center obar:gap-2", children: [_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-5 obar:w-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), _jsx("polyline", { points: "9 22 9 12 15 12 15 22" })] }), "Go to Home"] }), _jsxs("button", { onClick: () => loginWithRedirect(), className: "obar:flex-1 obar:px-6 obar:py-3 obar:rounded-lg obar:bg-indigo-600 obar:hover:bg-indigo-700 obar:text-slate-700 obar:dark:text-slate-200 obar:font-medium obar:transition-colors obar:shadow-lg obar:shadow-indigo-500/20 obar:dark:bg-indigo-500 obar:dark:hover:bg-indigo-600 obar:cursor-pointer obar:flex obar:items-center obar:justify-center obar:gap-2", children: ["Sign In", _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "obar:h-5 obar:w-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" }), _jsx("polyline", { points: "10 17 15 12 10 7" }), _jsx("line", { x1: "15", y1: "12", x2: "3", y2: "12" })] })] })] }), _jsx("button", { onClick: () => window.history.back(), className: "obar:text-sm obar:text-slate-500 obar:hover:text-slate-700 obar:dark:text-slate-400 obar:dark:hover:text-slate-200 obar:underline obar:underline-offset-4 obar:transition-colors obar:cursor-pointer", children: "\u2190 Go back to previous page" })] })] }), (supportEmail || supportUrl) && (_jsx("div", { className: "obar:mt-8 obar:pt-6 obar:border-t obar:border-slate-200 obar:dark:border-slate-700", children: _jsxs("p", { className: "obar:text-sm obar:text-slate-500 obar:dark:text-slate-400 obar:text-center", children: ["Need help?", ' ', _jsx("a", { href: supportUrl || `mailto:${supportEmail}`, className: "obar:text-indigo-600 obar:dark:text-indigo-400 obar:hover:underline obar:font-medium obar:cursor-pointer", children: "Contact support" })] }) }))] }) }));
|
|
6
|
+
}
|
|
7
|
+
export default Unauthorized;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode JWT token payload without external dependencies.
|
|
3
|
+
* Returns the decoded payload or null if invalid.
|
|
4
|
+
*/
|
|
5
|
+
export function decodeJWT(token) {
|
|
6
|
+
try {
|
|
7
|
+
const parts = token.split('.');
|
|
8
|
+
if (parts.length !== 3) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
// Decode base64url (replace URL-safe chars and pad)
|
|
12
|
+
if (parts[1] === undefined) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const base64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');
|
|
16
|
+
const paddedBase64 = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '=');
|
|
17
|
+
const jsonPayload = decodeURIComponent(atob(paddedBase64)
|
|
18
|
+
.split('')
|
|
19
|
+
.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
|
|
20
|
+
.join(''));
|
|
21
|
+
return JSON.parse(jsonPayload);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.error('Failed to decode JWT:', error);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|