@cas-system/nextjs-cas-client 1.0.0 → 1.0.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/{CasProvider.d.ts → cjs/CasProvider.d.ts} +1 -1
- package/dist/cjs/CasProvider.d.ts.map +1 -0
- package/dist/cjs/CasProvider.js +154 -0
- package/dist/cjs/CasProvider.js.map +1 -0
- package/dist/cjs/components/CasLoginButton.d.ts.map +1 -0
- package/dist/cjs/components/CasLoginButton.js +26 -0
- package/dist/cjs/components/CasLoginButton.js.map +1 -0
- package/dist/cjs/components/CasProtectedRoute.d.ts.map +1 -0
- package/dist/cjs/components/CasProtectedRoute.js +61 -0
- package/dist/cjs/components/CasProtectedRoute.js.map +1 -0
- package/dist/{handlers → cjs/handlers}/callback.d.ts +2 -2
- package/dist/cjs/handlers/callback.d.ts.map +1 -0
- package/dist/cjs/handlers/callback.js +68 -0
- package/dist/cjs/handlers/callback.js.map +1 -0
- package/dist/cjs/handlers/index.d.ts +8 -0
- package/dist/cjs/handlers/index.d.ts.map +1 -0
- package/dist/cjs/handlers/index.js +14 -0
- package/dist/cjs/handlers/index.js.map +1 -0
- package/dist/{handlers → cjs/handlers}/logout.d.ts +2 -2
- package/dist/cjs/handlers/logout.d.ts.map +1 -0
- package/dist/cjs/handlers/logout.js +64 -0
- package/dist/cjs/handlers/logout.js.map +1 -0
- package/dist/{handlers → cjs/handlers}/user.d.ts +1 -1
- package/dist/cjs/handlers/user.d.ts.map +1 -0
- package/dist/cjs/handlers/user.js +47 -0
- package/dist/cjs/handlers/user.js.map +1 -0
- package/dist/{hooks → cjs/hooks}/useCasAuth.d.ts +1 -1
- package/dist/cjs/hooks/useCasAuth.d.ts.map +1 -0
- package/dist/cjs/hooks/useCasAuth.js +17 -0
- package/dist/cjs/hooks/useCasAuth.js.map +1 -0
- package/dist/{hooks → cjs/hooks}/useCasUser.d.ts +1 -1
- package/dist/cjs/hooks/useCasUser.d.ts.map +1 -0
- package/dist/cjs/hooks/useCasUser.js +48 -0
- package/dist/cjs/hooks/useCasUser.js.map +1 -0
- package/dist/{index.d.ts → cjs/index.d.ts} +10 -10
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +26 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/{middleware.d.ts → cjs/middleware.d.ts} +2 -2
- package/dist/cjs/middleware.d.ts.map +1 -0
- package/dist/cjs/middleware.js +114 -0
- package/dist/cjs/middleware.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/{server → cjs/server}/auth.d.ts +2 -2
- package/dist/cjs/server/auth.d.ts.map +1 -0
- package/dist/cjs/server/auth.js +222 -0
- package/dist/cjs/server/auth.js.map +1 -0
- package/dist/{server → cjs/server}/cas-client.d.ts +1 -1
- package/dist/cjs/server/cas-client.d.ts.map +1 -0
- package/dist/cjs/server/cas-client.js +226 -0
- package/dist/cjs/server/cas-client.js.map +1 -0
- package/dist/{server → cjs/server}/index.d.ts +3 -3
- package/dist/cjs/server/index.d.ts.map +1 -0
- package/dist/cjs/server/index.js +20 -0
- package/dist/cjs/server/index.js.map +1 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +7 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/CasProvider.d.ts +63 -0
- package/dist/esm/CasProvider.d.ts.map +1 -0
- package/dist/esm/CasProvider.js.map +1 -0
- package/dist/esm/components/CasLoginButton.d.ts +36 -0
- package/dist/esm/components/CasLoginButton.d.ts.map +1 -0
- package/dist/{components → esm/components}/CasLoginButton.js +1 -1
- package/dist/esm/components/CasLoginButton.js.map +1 -0
- package/dist/esm/components/CasProtectedRoute.d.ts +51 -0
- package/dist/esm/components/CasProtectedRoute.d.ts.map +1 -0
- package/dist/{components → esm/components}/CasProtectedRoute.js +1 -1
- package/dist/esm/components/CasProtectedRoute.js.map +1 -0
- package/dist/esm/handlers/callback.d.ts +39 -0
- package/dist/esm/handlers/callback.d.ts.map +1 -0
- package/dist/{handlers → esm/handlers}/callback.js +4 -4
- package/dist/esm/handlers/callback.js.map +1 -0
- package/dist/esm/handlers/index.d.ts +8 -0
- package/dist/esm/handlers/index.d.ts.map +1 -0
- package/dist/esm/handlers/index.js +8 -0
- package/dist/esm/handlers/index.js.map +1 -0
- package/dist/esm/handlers/logout.d.ts +36 -0
- package/dist/esm/handlers/logout.d.ts.map +1 -0
- package/dist/{handlers → esm/handlers}/logout.js +4 -4
- package/dist/esm/handlers/logout.js.map +1 -0
- package/dist/esm/handlers/user.d.ts +27 -0
- package/dist/esm/handlers/user.d.ts.map +1 -0
- package/dist/{handlers → esm/handlers}/user.js +3 -3
- package/dist/esm/handlers/user.js.map +1 -0
- package/dist/esm/hooks/useCasAuth.d.ts +32 -0
- package/dist/esm/hooks/useCasAuth.d.ts.map +1 -0
- package/dist/{hooks → esm/hooks}/useCasAuth.js +1 -1
- package/dist/esm/hooks/useCasAuth.js.map +1 -0
- package/dist/esm/hooks/useCasUser.d.ts +33 -0
- package/dist/esm/hooks/useCasUser.d.ts.map +1 -0
- package/dist/{hooks → esm/hooks}/useCasUser.js +1 -1
- package/dist/esm/hooks/useCasUser.js.map +1 -0
- package/dist/esm/index.d.ts +19 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/{index.js → esm/index.js} +5 -5
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/middleware.d.ts +40 -0
- package/dist/esm/middleware.d.ts.map +1 -0
- package/dist/{middleware.js → esm/middleware.js} +2 -2
- package/dist/esm/middleware.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/server/auth.d.ts +111 -0
- package/dist/esm/server/auth.d.ts.map +1 -0
- package/dist/{server → esm/server}/auth.js +1 -1
- package/dist/esm/server/auth.js.map +1 -0
- package/dist/esm/server/cas-client.d.ts +93 -0
- package/dist/esm/server/cas-client.d.ts.map +1 -0
- package/dist/esm/server/cas-client.js.map +1 -0
- package/dist/esm/server/index.d.ts +12 -0
- package/dist/esm/server/index.d.ts.map +1 -0
- package/dist/{server → esm/server}/index.js +2 -2
- package/dist/esm/server/index.js.map +1 -0
- package/dist/esm/types.d.ts +170 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +39 -19
- package/dist/CasProvider.d.ts.map +0 -1
- package/dist/CasProvider.js.map +0 -1
- package/dist/components/CasLoginButton.d.ts.map +0 -1
- package/dist/components/CasLoginButton.js.map +0 -1
- package/dist/components/CasProtectedRoute.d.ts.map +0 -1
- package/dist/components/CasProtectedRoute.js.map +0 -1
- package/dist/handlers/callback.d.ts.map +0 -1
- package/dist/handlers/callback.js.map +0 -1
- package/dist/handlers/index.d.ts +0 -8
- package/dist/handlers/index.d.ts.map +0 -1
- package/dist/handlers/index.js +0 -8
- package/dist/handlers/index.js.map +0 -1
- package/dist/handlers/logout.d.ts.map +0 -1
- package/dist/handlers/logout.js.map +0 -1
- package/dist/handlers/user.d.ts.map +0 -1
- package/dist/handlers/user.js.map +0 -1
- package/dist/hooks/useCasAuth.d.ts.map +0 -1
- package/dist/hooks/useCasAuth.js.map +0 -1
- package/dist/hooks/useCasUser.d.ts.map +0 -1
- package/dist/hooks/useCasUser.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/middleware.d.ts.map +0 -1
- package/dist/middleware.js.map +0 -1
- package/dist/server/auth.d.ts.map +0 -1
- package/dist/server/auth.js.map +0 -1
- package/dist/server/cas-client.d.ts.map +0 -1
- package/dist/server/cas-client.js.map +0 -1
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- /package/dist/{components → cjs/components}/CasLoginButton.d.ts +0 -0
- /package/dist/{components → cjs/components}/CasProtectedRoute.d.ts +0 -0
- /package/dist/{types.d.ts → cjs/types.d.ts} +0 -0
- /package/dist/{CasProvider.js → esm/CasProvider.js} +0 -0
- /package/dist/{server → esm/server}/cas-client.js +0 -0
- /package/dist/{types.js → esm/types.js} +0 -0
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
import React from 'react';
|
|
24
|
-
import type { CasAuthContext } from './types';
|
|
24
|
+
import type { CasAuthContext } from './types.js';
|
|
25
25
|
/** Props accepted by {@link CasProvider}. */
|
|
26
26
|
export interface CasProviderProps {
|
|
27
27
|
children: React.ReactNode;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CasProvider.d.ts","sourceRoot":"","sources":["../../src/CasProvider.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,YAAY,CAAC;AAY1D,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,YAA8B,EAC9B,cAAkC,EAClC,QAAQ,EAAE,YAAY,EACtB,YAAY,EACZ,WAAW,EACX,cAAc,GACf,EAAE,gBAAgB,qBA8GlB;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CASlD"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.CasProvider = CasProvider;
|
|
5
|
+
exports.useCasAuthContext = useCasAuthContext;
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
/**
|
|
8
|
+
* @module @cas-system/nextjs-cas-client/CasProvider
|
|
9
|
+
* @description Client-side React context provider that manages CAS
|
|
10
|
+
* authentication state. Fetches the current session from
|
|
11
|
+
* `/api/cas/user` on mount and exposes login / logout / refresh actions.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // app/layout.tsx
|
|
16
|
+
* import { CasProvider } from '@cas-system/nextjs-cas-client';
|
|
17
|
+
*
|
|
18
|
+
* export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
19
|
+
* return (
|
|
20
|
+
* <html>
|
|
21
|
+
* <body>
|
|
22
|
+
* <CasProvider>{children}</CasProvider>
|
|
23
|
+
* </body>
|
|
24
|
+
* </html>
|
|
25
|
+
* );
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
const react_1 = require("react");
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Context
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
const CasContext = (0, react_1.createContext)(undefined);
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Provider component
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
/**
|
|
38
|
+
* Client-side authentication provider.
|
|
39
|
+
*
|
|
40
|
+
* Wrap your application (typically in `app/layout.tsx`) with this provider to
|
|
41
|
+
* make CAS auth state available to all client components via the
|
|
42
|
+
* {@link useCasAuth} and {@link useCasUser} hooks.
|
|
43
|
+
*/
|
|
44
|
+
function CasProvider({ children, userEndpoint = '/api/cas/user', logoutEndpoint = '/api/cas/logout', loginUrl: loginUrlProp, casServerUrl, casClientId, casCallbackUrl, }) {
|
|
45
|
+
const [user, setUser] = (0, react_1.useState)(null);
|
|
46
|
+
const [isLoading, setIsLoading] = (0, react_1.useState)(true);
|
|
47
|
+
const [error, setError] = (0, react_1.useState)(null);
|
|
48
|
+
// -----------------------------------------------------------------------
|
|
49
|
+
// Fetch current session
|
|
50
|
+
// -----------------------------------------------------------------------
|
|
51
|
+
const fetchUser = (0, react_1.useCallback)(async () => {
|
|
52
|
+
setIsLoading(true);
|
|
53
|
+
setError(null);
|
|
54
|
+
try {
|
|
55
|
+
const res = await fetch(userEndpoint, {
|
|
56
|
+
credentials: 'same-origin',
|
|
57
|
+
cache: 'no-store',
|
|
58
|
+
});
|
|
59
|
+
if (res.ok) {
|
|
60
|
+
const data = (await res.json());
|
|
61
|
+
setUser(data.user ?? null);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
setUser(null);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
setUser(null);
|
|
69
|
+
setError(err instanceof Error ? err : new Error('Failed to fetch CAS session'));
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
setIsLoading(false);
|
|
73
|
+
}
|
|
74
|
+
}, [userEndpoint]);
|
|
75
|
+
(0, react_1.useEffect)(() => {
|
|
76
|
+
void fetchUser();
|
|
77
|
+
}, [fetchUser]);
|
|
78
|
+
// -----------------------------------------------------------------------
|
|
79
|
+
// Actions
|
|
80
|
+
// -----------------------------------------------------------------------
|
|
81
|
+
const login = (0, react_1.useCallback)((returnUrl) => {
|
|
82
|
+
if (loginUrlProp) {
|
|
83
|
+
const url = new URL(loginUrlProp);
|
|
84
|
+
if (returnUrl)
|
|
85
|
+
url.searchParams.set('returnUrl', returnUrl);
|
|
86
|
+
window.location.href = url.toString();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (casServerUrl && casClientId) {
|
|
90
|
+
const callback = casCallbackUrl ??
|
|
91
|
+
`${window.location.origin}/api/cas/callback`;
|
|
92
|
+
const callbackWithReturn = new URL(callback);
|
|
93
|
+
if (returnUrl)
|
|
94
|
+
callbackWithReturn.searchParams.set('returnUrl', returnUrl);
|
|
95
|
+
const params = new URLSearchParams({
|
|
96
|
+
client_id: casClientId,
|
|
97
|
+
response_type: 'token',
|
|
98
|
+
redirect_uri: callbackWithReturn.toString(),
|
|
99
|
+
});
|
|
100
|
+
window.location.href = `${casServerUrl.replace(/\/+$/, '')}/sso/login?${params.toString()}`;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// Fallback — redirect to a local login page
|
|
104
|
+
const url = new URL('/login', window.location.origin);
|
|
105
|
+
if (returnUrl)
|
|
106
|
+
url.searchParams.set('returnUrl', returnUrl);
|
|
107
|
+
window.location.href = url.toString();
|
|
108
|
+
}, [loginUrlProp, casServerUrl, casClientId, casCallbackUrl]);
|
|
109
|
+
const logout = (0, react_1.useCallback)(async () => {
|
|
110
|
+
try {
|
|
111
|
+
await fetch(logoutEndpoint, {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
credentials: 'same-origin',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Ignore — cookie might already be gone
|
|
118
|
+
}
|
|
119
|
+
setUser(null);
|
|
120
|
+
window.location.href = '/';
|
|
121
|
+
}, [logoutEndpoint]);
|
|
122
|
+
const refresh = (0, react_1.useCallback)(async () => {
|
|
123
|
+
await fetchUser();
|
|
124
|
+
}, [fetchUser]);
|
|
125
|
+
// -----------------------------------------------------------------------
|
|
126
|
+
// Memoised context value
|
|
127
|
+
// -----------------------------------------------------------------------
|
|
128
|
+
const value = (0, react_1.useMemo)(() => ({
|
|
129
|
+
user,
|
|
130
|
+
isLoading,
|
|
131
|
+
isAuthenticated: !!user,
|
|
132
|
+
error,
|
|
133
|
+
login,
|
|
134
|
+
logout,
|
|
135
|
+
refresh,
|
|
136
|
+
}), [user, isLoading, error, login, logout, refresh]);
|
|
137
|
+
return (0, jsx_runtime_1.jsx)(CasContext.Provider, { value: value, children: children });
|
|
138
|
+
}
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// Hook (also re-exported from hooks/)
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
/**
|
|
143
|
+
* Access the CAS auth context. Must be called inside a `<CasProvider>`.
|
|
144
|
+
* @throws If used outside of a `CasProvider`.
|
|
145
|
+
*/
|
|
146
|
+
function useCasAuthContext() {
|
|
147
|
+
const ctx = (0, react_1.useContext)(CasContext);
|
|
148
|
+
if (!ctx) {
|
|
149
|
+
throw new Error('useCasAuthContext must be used within a <CasProvider>. ' +
|
|
150
|
+
'Wrap your app in <CasProvider> in your root layout.');
|
|
151
|
+
}
|
|
152
|
+
return ctx;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=CasProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CasProvider.js","sourceRoot":"","sources":["../../src/CasProvider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CasLoginButton.d.ts","sourceRoot":"","sources":["../../../src/components/CasLoginButton.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,wCAAwC;AACxC,MAAM,WAAW,mBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IACtE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAoB,EACpB,SAAS,EACT,GAAG,WAAW,EACf,EAAE,mBAAmB,4BA8BrB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.CasLoginButton = CasLoginButton;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const CasProvider_js_1 = require("../CasProvider.js");
|
|
7
|
+
/**
|
|
8
|
+
* A simple button that triggers the CAS login flow.
|
|
9
|
+
*
|
|
10
|
+
* When the user is already authenticated the button renders nothing by
|
|
11
|
+
* default. Customise this via the {@link CasLoginButtonProps}.
|
|
12
|
+
*/
|
|
13
|
+
function CasLoginButton({ children = 'Sign in', returnUrl, ...buttonProps }) {
|
|
14
|
+
const { isAuthenticated, isLoading, login } = (0, CasProvider_js_1.useCasAuthContext)();
|
|
15
|
+
if (isLoading) {
|
|
16
|
+
return ((0, jsx_runtime_1.jsx)("button", { ...buttonProps, disabled: true, children: "Loading\u2026" }));
|
|
17
|
+
}
|
|
18
|
+
if (isAuthenticated) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return ((0, jsx_runtime_1.jsx)("button", { ...buttonProps, onClick: () => login(returnUrl ??
|
|
22
|
+
(typeof window !== 'undefined'
|
|
23
|
+
? window.location.pathname + window.location.search
|
|
24
|
+
: undefined)), children: children }));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=CasLoginButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CasLoginButton.js","sourceRoot":"","sources":["../../../src/components/CasLoginButton.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AA0Cb,wCAkCC;;AAtDD,sDAAsD;AActD;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,EAC7B,QAAQ,GAAG,SAAS,EACpB,SAAS,EACT,GAAG,WAAW,EACM;IACpB,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAA,kCAAiB,GAAE,CAAC;IAElE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CACL,sCAAY,WAAW,EAAE,QAAQ,oCAExB,CACV,CAAC;IACJ,CAAC;IAED,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,sCACM,WAAW,EACf,OAAO,EAAE,GAAG,EAAE,CACZ,KAAK,CACH,SAAS;YACP,CAAC,OAAO,MAAM,KAAK,WAAW;gBAC5B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM;gBACnD,CAAC,CAAC,SAAS,CAAC,CACjB,YAGF,QAAQ,GACF,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CasProtectedRoute.d.ts","sourceRoot":"","sources":["../../../src/components/CasProtectedRoute.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAoB,MAAM,OAAO,CAAC;AAGzC,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB;;;OAGG;IACH,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAElC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEvC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,KAAK,EACL,eAAe,EACf,oBAAoB,EACpB,UAAU,GACX,EAAE,sBAAsB,qBAmCxB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.CasProtectedRoute = CasProtectedRoute;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
/**
|
|
7
|
+
* @module @cas-system/nextjs-cas-client/components/CasProtectedRoute
|
|
8
|
+
* @description Client component that guards its children behind CAS
|
|
9
|
+
* authentication. Shows a loading state while the session is being
|
|
10
|
+
* fetched and redirects to login when no valid session exists.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { CasProtectedRoute } from '@cas-system/nextjs-cas-client';
|
|
15
|
+
*
|
|
16
|
+
* export default function SecretPage() {
|
|
17
|
+
* return (
|
|
18
|
+
* <CasProtectedRoute>
|
|
19
|
+
* <h1>Secret Content</h1>
|
|
20
|
+
* </CasProtectedRoute>
|
|
21
|
+
* );
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
const react_1 = require("react");
|
|
26
|
+
const CasProvider_js_1 = require("../CasProvider.js");
|
|
27
|
+
/**
|
|
28
|
+
* Client component that only renders its children when the user is
|
|
29
|
+
* authenticated (and optionally has the required roles).
|
|
30
|
+
*/
|
|
31
|
+
function CasProtectedRoute({ children, roles, loadingFallback, unauthorizedFallback, redirectTo, }) {
|
|
32
|
+
const { user, isLoading, isAuthenticated, login } = (0, CasProvider_js_1.useCasAuthContext)();
|
|
33
|
+
(0, react_1.useEffect)(() => {
|
|
34
|
+
if (!isLoading && !isAuthenticated) {
|
|
35
|
+
if (redirectTo) {
|
|
36
|
+
window.location.href = redirectTo;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
login(window.location.pathname + window.location.search);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}, [isLoading, isAuthenticated, login, redirectTo]);
|
|
43
|
+
// Still loading
|
|
44
|
+
if (isLoading) {
|
|
45
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: loadingFallback ?? (0, jsx_runtime_1.jsx)("p", { children: "Loading\u2026" }) });
|
|
46
|
+
}
|
|
47
|
+
// Not authenticated — will redirect in useEffect
|
|
48
|
+
if (!isAuthenticated) {
|
|
49
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: loadingFallback ?? (0, jsx_runtime_1.jsx)("p", { children: "Redirecting to login\u2026" }) });
|
|
50
|
+
}
|
|
51
|
+
// Role check
|
|
52
|
+
if (roles && roles.length > 0) {
|
|
53
|
+
const userRoles = user?.roles ?? [];
|
|
54
|
+
const hasRequiredRoles = roles.every((r) => userRoles.includes(r));
|
|
55
|
+
if (!hasRequiredRoles) {
|
|
56
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: unauthorizedFallback ?? (0, jsx_runtime_1.jsx)("p", { children: "Access denied \u2014 insufficient permissions." }) }));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=CasProtectedRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CasProtectedRoute.js","sourceRoot":"","sources":["../../../src/components/CasProtectedRoute.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AA2Db,8CAyCC;;AAlGD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,iCAAyC;AACzC,sDAAsD;AAgCtD;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,KAAK,EACL,eAAe,EACf,oBAAoB,EACpB,UAAU,GACa;IACvB,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,IAAA,kCAAiB,GAAE,CAAC;IAExE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,SAAS,IAAI,CAAC,eAAe,EAAE,CAAC;YACnC,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,UAAU,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IAEpD,gBAAgB;IAChB,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,2DAAG,eAAe,IAAI,0DAAe,GAAI,CAAC;IACnD,CAAC;IAED,iDAAiD;IACjD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,2DAAG,eAAe,IAAI,uEAA4B,GAAI,CAAC;IAChE,CAAC;IAED,aAAa;IACb,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QACpC,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,CACL,2DAAG,oBAAoB,IAAI,2FAAgD,GAAI,CAChF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,2DAAG,QAAQ,GAAI,CAAC;AACzB,CAAC"}
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
* export { handler as GET };
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
31
|
-
import type { CasHandlerConfig } from '../types';
|
|
30
|
+
import { NextRequest, NextResponse } from 'next/server.js';
|
|
31
|
+
import type { CasHandlerConfig } from '../types.js';
|
|
32
32
|
/**
|
|
33
33
|
* Create a GET handler for `/api/cas/callback`.
|
|
34
34
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../src/handlers/callback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,IAIlC,SAAS,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,CA4BvE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module @cas-system/nextjs-cas-client/handlers/callback
|
|
4
|
+
* @description API route handler for the CAS SSO callback endpoint.
|
|
5
|
+
*
|
|
6
|
+
* After the CAS server authenticates the user it redirects to
|
|
7
|
+
* `{callbackUrl}?token=JWT_TOKEN`. This handler:
|
|
8
|
+
*
|
|
9
|
+
* 1. Extracts the `token` query parameter.
|
|
10
|
+
* 2. Validates it server-side via the CAS `/api/validate-token` endpoint.
|
|
11
|
+
* 3. Sets an encrypted session cookie.
|
|
12
|
+
* 4. Redirects the user to the intended URL (or `/`).
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // app/api/cas/callback/route.ts
|
|
17
|
+
* import { createCallbackHandler } from '@cas-system/nextjs-cas-client/handlers';
|
|
18
|
+
*
|
|
19
|
+
* const handler = createCallbackHandler({
|
|
20
|
+
* cas: {
|
|
21
|
+
* serverUrl: process.env.CAS_SERVER_URL!,
|
|
22
|
+
* clientId: process.env.CAS_CLIENT_ID!,
|
|
23
|
+
* clientSecret: process.env.CAS_CLIENT_SECRET!,
|
|
24
|
+
* },
|
|
25
|
+
* afterLoginUrl: '/dashboard',
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* export { handler as GET };
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.createCallbackHandler = createCallbackHandler;
|
|
33
|
+
const server_js_1 = require("next/server.js");
|
|
34
|
+
const headers_js_1 = require("next/headers.js");
|
|
35
|
+
const cas_client_js_1 = require("../server/cas-client.js");
|
|
36
|
+
const auth_js_1 = require("../server/auth.js");
|
|
37
|
+
/**
|
|
38
|
+
* Create a GET handler for `/api/cas/callback`.
|
|
39
|
+
*
|
|
40
|
+
* @param config - Handler configuration including CAS server details.
|
|
41
|
+
* @returns A Next.js App Router GET handler.
|
|
42
|
+
*/
|
|
43
|
+
function createCallbackHandler(config) {
|
|
44
|
+
const cas = new cas_client_js_1.CasClient(config.cas);
|
|
45
|
+
const afterLoginUrl = config.afterLoginUrl ?? '/';
|
|
46
|
+
return async function GET(request) {
|
|
47
|
+
const { searchParams } = request.nextUrl;
|
|
48
|
+
const token = searchParams.get('token');
|
|
49
|
+
const returnUrl = searchParams.get('returnUrl') ?? afterLoginUrl;
|
|
50
|
+
if (!token) {
|
|
51
|
+
console.error('[CasCallback] No token query parameter received.');
|
|
52
|
+
return server_js_1.NextResponse.redirect(new URL('/login?error=no_token', request.url));
|
|
53
|
+
}
|
|
54
|
+
// Validate the token server-side
|
|
55
|
+
const user = await cas.validateToken(token);
|
|
56
|
+
if (!user) {
|
|
57
|
+
console.error('[CasCallback] Token validation failed.');
|
|
58
|
+
return server_js_1.NextResponse.redirect(new URL('/login?error=invalid_token', request.url));
|
|
59
|
+
}
|
|
60
|
+
// Set session cookie
|
|
61
|
+
const cookieStore = await (0, headers_js_1.cookies)();
|
|
62
|
+
await (0, auth_js_1.setCasSession)(cookieStore, user, token);
|
|
63
|
+
// Redirect to the intended URL
|
|
64
|
+
const redirectUrl = new URL(returnUrl, request.url);
|
|
65
|
+
return server_js_1.NextResponse.redirect(redirectUrl);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=callback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../src/handlers/callback.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;AAcH,sDAgCC;AA5CD,8CAA2D;AAC3D,gDAA0C;AAE1C,2DAAoD;AACpD,+CAAkD;AAElD;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,MAAwB;IAC5D,MAAM,GAAG,GAAG,IAAI,yBAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,GAAG,CAAC;IAElD,OAAO,KAAK,UAAU,GAAG,CAAC,OAAoB;QAC5C,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QACzC,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,aAAa,CAAC;QAEjE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YAClE,OAAO,wBAAY,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,uBAAuB,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9E,CAAC;QAED,iCAAiC;QACjC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE5C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACxD,OAAO,wBAAY,CAAC,QAAQ,CAC1B,IAAI,GAAG,CAAC,4BAA4B,EAAE,OAAO,CAAC,GAAG,CAAC,CACnD,CAAC;QACJ,CAAC;QAED,qBAAqB;QACrB,MAAM,WAAW,GAAG,MAAM,IAAA,oBAAO,GAAE,CAAC;QACpC,MAAM,IAAA,uBAAa,EAAC,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAE9C,+BAA+B;QAC/B,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QACpD,OAAO,wBAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @cas-system/nextjs-cas-client/handlers
|
|
3
|
+
* @description Re-exports all API route handler factories.
|
|
4
|
+
*/
|
|
5
|
+
export { createCallbackHandler } from './callback.js';
|
|
6
|
+
export { createLogoutHandler } from './logout.js';
|
|
7
|
+
export { createUserHandler } from './user.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module @cas-system/nextjs-cas-client/handlers
|
|
4
|
+
* @description Re-exports all API route handler factories.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createUserHandler = exports.createLogoutHandler = exports.createCallbackHandler = void 0;
|
|
8
|
+
var callback_js_1 = require("./callback.js");
|
|
9
|
+
Object.defineProperty(exports, "createCallbackHandler", { enumerable: true, get: function () { return callback_js_1.createCallbackHandler; } });
|
|
10
|
+
var logout_js_1 = require("./logout.js");
|
|
11
|
+
Object.defineProperty(exports, "createLogoutHandler", { enumerable: true, get: function () { return logout_js_1.createLogoutHandler; } });
|
|
12
|
+
var user_js_1 = require("./user.js");
|
|
13
|
+
Object.defineProperty(exports, "createUserHandler", { enumerable: true, get: function () { return user_js_1.createUserHandler; } });
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/handlers/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6CAAsD;AAA7C,oHAAA,qBAAqB,OAAA;AAC9B,yCAAkD;AAAzC,gHAAA,mBAAmB,OAAA;AAC5B,qCAA8C;AAArC,4GAAA,iBAAiB,OAAA"}
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
* export { handler as POST };
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
28
|
-
import type { CasHandlerConfig } from '../types';
|
|
27
|
+
import { NextRequest, NextResponse } from 'next/server.js';
|
|
28
|
+
import type { CasHandlerConfig } from '../types.js';
|
|
29
29
|
/**
|
|
30
30
|
* Create a POST handler for `/api/cas/logout`.
|
|
31
31
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../../src/handlers/logout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,IAI/B,SAAS,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,CAyBxE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module @cas-system/nextjs-cas-client/handlers/logout
|
|
4
|
+
* @description API route handler for the CAS logout endpoint.
|
|
5
|
+
*
|
|
6
|
+
* 1. Reads the session to obtain the JWT token.
|
|
7
|
+
* 2. Notifies the CAS server of the logout.
|
|
8
|
+
* 3. Clears the session cookies.
|
|
9
|
+
* 4. Redirects the user (or returns 200 for API calls).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // app/api/cas/logout/route.ts
|
|
14
|
+
* import { createLogoutHandler } from '@cas-system/nextjs-cas-client/handlers';
|
|
15
|
+
*
|
|
16
|
+
* const handler = createLogoutHandler({
|
|
17
|
+
* cas: {
|
|
18
|
+
* serverUrl: process.env.CAS_SERVER_URL!,
|
|
19
|
+
* clientId: process.env.CAS_CLIENT_ID!,
|
|
20
|
+
* clientSecret: process.env.CAS_CLIENT_SECRET!,
|
|
21
|
+
* },
|
|
22
|
+
* afterLogoutUrl: '/',
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* export { handler as POST };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.createLogoutHandler = createLogoutHandler;
|
|
30
|
+
const server_js_1 = require("next/server.js");
|
|
31
|
+
const headers_js_1 = require("next/headers.js");
|
|
32
|
+
const cas_client_js_1 = require("../server/cas-client.js");
|
|
33
|
+
const auth_js_1 = require("../server/auth.js");
|
|
34
|
+
/**
|
|
35
|
+
* Create a POST handler for `/api/cas/logout`.
|
|
36
|
+
*
|
|
37
|
+
* @param config - Handler configuration.
|
|
38
|
+
* @returns A Next.js App Router POST handler.
|
|
39
|
+
*/
|
|
40
|
+
function createLogoutHandler(config) {
|
|
41
|
+
const cas = new cas_client_js_1.CasClient(config.cas);
|
|
42
|
+
const afterLogoutUrl = config.afterLogoutUrl ?? '/';
|
|
43
|
+
return async function POST(request) {
|
|
44
|
+
const cookieStore = await (0, headers_js_1.cookies)();
|
|
45
|
+
// Attempt to read the current session for the token
|
|
46
|
+
const session = await (0, auth_js_1.getCasSession)(cookieStore);
|
|
47
|
+
// Notify the CAS server (best-effort)
|
|
48
|
+
if (session?.token) {
|
|
49
|
+
await cas.logout(session.token).catch(() => {
|
|
50
|
+
// Swallow — the local session will be cleared regardless
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// Clear local session cookies
|
|
54
|
+
(0, auth_js_1.clearCasSession)(cookieStore);
|
|
55
|
+
// If the request expects JSON (e.g. fetch from client), return 200
|
|
56
|
+
const accept = request.headers.get('accept') ?? '';
|
|
57
|
+
if (accept.includes('application/json')) {
|
|
58
|
+
return server_js_1.NextResponse.json({ success: true });
|
|
59
|
+
}
|
|
60
|
+
// Otherwise redirect
|
|
61
|
+
return server_js_1.NextResponse.redirect(new URL(afterLogoutUrl, request.url));
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../../src/handlers/logout.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;AAcH,kDA6BC;AAzCD,8CAA2D;AAC3D,gDAA0C;AAE1C,2DAAoD;AACpD,+CAAmE;AAEnE;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,MAAwB;IAC1D,MAAM,GAAG,GAAG,IAAI,yBAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,GAAG,CAAC;IAEpD,OAAO,KAAK,UAAU,IAAI,CAAC,OAAoB;QAC7C,MAAM,WAAW,GAAG,MAAM,IAAA,oBAAO,GAAE,CAAC;QAEpC,oDAAoD;QACpD,MAAM,OAAO,GAAG,MAAM,IAAA,uBAAa,EAAC,WAAW,CAAC,CAAC;QAEjD,sCAAsC;QACtC,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;YACnB,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBACzC,yDAAyD;YAC3D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,8BAA8B;QAC9B,IAAA,yBAAe,EAAC,WAAW,CAAC,CAAC;QAE7B,mEAAmE;QACnE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnD,IAAI,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACxC,OAAO,wBAAY,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,qBAAqB;QACrB,OAAO,wBAAY,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/handlers/user.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI9C;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,UACF,OAAO,CAAC,YAAY,CAAC,CAsBnD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module @cas-system/nextjs-cas-client/handlers/user
|
|
4
|
+
* @description API route handler that returns the current CAS user from
|
|
5
|
+
* the session cookie. This endpoint is called by the client-side
|
|
6
|
+
* `CasProvider` to hydrate the auth state.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // app/api/cas/user/route.ts
|
|
11
|
+
* import { createUserHandler } from '@cas-system/nextjs-cas-client/handlers';
|
|
12
|
+
*
|
|
13
|
+
* const handler = createUserHandler();
|
|
14
|
+
* export { handler as GET };
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.createUserHandler = createUserHandler;
|
|
19
|
+
const server_js_1 = require("next/server.js");
|
|
20
|
+
const headers_js_1 = require("next/headers.js");
|
|
21
|
+
const auth_js_1 = require("../server/auth.js");
|
|
22
|
+
/**
|
|
23
|
+
* Create a GET handler for `/api/cas/user`.
|
|
24
|
+
*
|
|
25
|
+
* Returns `{ user: CasUser }` when authenticated, or `401` otherwise.
|
|
26
|
+
* The response includes `Cache-Control: no-store` to prevent caching of
|
|
27
|
+
* auth state.
|
|
28
|
+
*
|
|
29
|
+
* @returns A Next.js App Router GET handler.
|
|
30
|
+
*/
|
|
31
|
+
function createUserHandler() {
|
|
32
|
+
return async function GET() {
|
|
33
|
+
const cookieStore = await (0, headers_js_1.cookies)();
|
|
34
|
+
const session = await (0, auth_js_1.getCasSession)(cookieStore);
|
|
35
|
+
if (!session) {
|
|
36
|
+
return server_js_1.NextResponse.json({ user: null, error: 'Not authenticated' }, {
|
|
37
|
+
status: 401,
|
|
38
|
+
headers: { 'Cache-Control': 'no-store' },
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return server_js_1.NextResponse.json({ user: session.user }, {
|
|
42
|
+
status: 200,
|
|
43
|
+
headers: { 'Cache-Control': 'no-store' },
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../../src/handlers/user.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AAeH,8CAuBC;AApCD,8CAA8C;AAC9C,gDAA0C;AAC1C,+CAAkD;AAElD;;;;;;;;GAQG;AACH,SAAgB,iBAAiB;IAC/B,OAAO,KAAK,UAAU,GAAG;QACvB,MAAM,WAAW,GAAG,MAAM,IAAA,oBAAO,GAAE,CAAC;QACpC,MAAM,OAAO,GAAG,MAAM,IAAA,uBAAa,EAAC,WAAW,CAAC,CAAC;QAEjD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,wBAAY,CAAC,IAAI,CACtB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAC1C;gBACE,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE;aACzC,CACF,CAAC;QACJ,CAAC;QAED,OAAO,wBAAY,CAAC,IAAI,CACtB,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EACtB;YACE,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE;SACzC,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCasAuth.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCasAuth.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,cAAc,CAE3C"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useCasAuth = useCasAuth;
|
|
5
|
+
const CasProvider_js_1 = require("../CasProvider.js");
|
|
6
|
+
/**
|
|
7
|
+
* Access CAS authentication state and actions.
|
|
8
|
+
*
|
|
9
|
+
* This is a convenience re-export of the context hook. Must be used inside
|
|
10
|
+
* a `<CasProvider>`.
|
|
11
|
+
*
|
|
12
|
+
* @returns The full {@link CasAuthContext}.
|
|
13
|
+
*/
|
|
14
|
+
function useCasAuth() {
|
|
15
|
+
return (0, CasProvider_js_1.useCasAuthContext)();
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=useCasAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCasAuth.js","sourceRoot":"","sources":["../../../src/hooks/useCasAuth.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAmCb,gCAEC;AAZD,sDAAsD;AAEtD;;;;;;;GAOG;AACH,SAAgB,UAAU;IACxB,OAAO,IAAA,kCAAiB,GAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCasUser.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCasUser.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,yCAAyC;AACzC,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAErB,0DAA0D;IAC1D,SAAS,EAAE,OAAO,CAAC;IAEnB,sCAAsC;IACtC,eAAe,EAAE,OAAO,CAAC;IAEzB;;;;;OAKG;IACH,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAEzC;;;;;OAKG;IACH,UAAU,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAE5C,iFAAiF;IACjF,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,gBAAgB,CAsB7C"}
|