nextauthz 1.0.9 → 1.1.0
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.d.mts +24 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +100 -29
- package/dist/index.mjs +97 -29
- package/package.json +1 -1
- package/src/AuthGuard.tsx +56 -56
- package/src/AuthProvider.tsx +25 -25
- package/src/RoleGuard.tsx +40 -40
- package/src/index.ts +7 -7
- package/src/myAuth.ts +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import React__default, { ReactNode } from 'react';
|
|
3
4
|
|
|
4
5
|
type AuthContextType<UserType> = {
|
|
5
6
|
user: UserType | null;
|
|
@@ -22,8 +23,29 @@ declare function createAuthContext<UserType>(options?: AuthContextOptions): {
|
|
|
22
23
|
useAuth: () => AuthContextType<UserType>;
|
|
23
24
|
};
|
|
24
25
|
|
|
26
|
+
type AuthGuardProps = {
|
|
27
|
+
children: React__default.ReactNode;
|
|
28
|
+
redirectTo?: string;
|
|
29
|
+
tokenKey?: string;
|
|
30
|
+
refreshToken?: () => Promise<string | null>;
|
|
31
|
+
};
|
|
32
|
+
declare const AuthGuard: ({ children, redirectTo, tokenKey, refreshToken, }: AuthGuardProps) => react_jsx_runtime.JSX.Element | null;
|
|
33
|
+
|
|
34
|
+
type RoleGuardProps = {
|
|
35
|
+
children: React__default.ReactNode;
|
|
36
|
+
allowedRoles: string[];
|
|
37
|
+
redirectTo?: string;
|
|
38
|
+
};
|
|
39
|
+
declare const RoleGuard: React__default.FC<RoleGuardProps>;
|
|
40
|
+
|
|
25
41
|
type User = {
|
|
26
42
|
[key: string]: any;
|
|
27
43
|
};
|
|
44
|
+
declare function createAppAuth(storage?: 'localStorage' | 'sessionStorage' | 'cookie'): {
|
|
45
|
+
AuthProvider: ({ children }: {
|
|
46
|
+
children: React.ReactNode;
|
|
47
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
48
|
+
useAuth: () => AuthContextType<User>;
|
|
49
|
+
};
|
|
28
50
|
|
|
29
|
-
export { type User, createAuthContext };
|
|
51
|
+
export { AuthGuard, RoleGuard, type User, createAppAuth, createAuthContext };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import React__default, { ReactNode } from 'react';
|
|
3
4
|
|
|
4
5
|
type AuthContextType<UserType> = {
|
|
5
6
|
user: UserType | null;
|
|
@@ -22,8 +23,29 @@ declare function createAuthContext<UserType>(options?: AuthContextOptions): {
|
|
|
22
23
|
useAuth: () => AuthContextType<UserType>;
|
|
23
24
|
};
|
|
24
25
|
|
|
26
|
+
type AuthGuardProps = {
|
|
27
|
+
children: React__default.ReactNode;
|
|
28
|
+
redirectTo?: string;
|
|
29
|
+
tokenKey?: string;
|
|
30
|
+
refreshToken?: () => Promise<string | null>;
|
|
31
|
+
};
|
|
32
|
+
declare const AuthGuard: ({ children, redirectTo, tokenKey, refreshToken, }: AuthGuardProps) => react_jsx_runtime.JSX.Element | null;
|
|
33
|
+
|
|
34
|
+
type RoleGuardProps = {
|
|
35
|
+
children: React__default.ReactNode;
|
|
36
|
+
allowedRoles: string[];
|
|
37
|
+
redirectTo?: string;
|
|
38
|
+
};
|
|
39
|
+
declare const RoleGuard: React__default.FC<RoleGuardProps>;
|
|
40
|
+
|
|
25
41
|
type User = {
|
|
26
42
|
[key: string]: any;
|
|
27
43
|
};
|
|
44
|
+
declare function createAppAuth(storage?: 'localStorage' | 'sessionStorage' | 'cookie'): {
|
|
45
|
+
AuthProvider: ({ children }: {
|
|
46
|
+
children: React.ReactNode;
|
|
47
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
48
|
+
useAuth: () => AuthContextType<User>;
|
|
49
|
+
};
|
|
28
50
|
|
|
29
|
-
export { type User, createAuthContext };
|
|
51
|
+
export { AuthGuard, RoleGuard, type User, createAppAuth, createAuthContext };
|
package/dist/index.js
CHANGED
|
@@ -1699,18 +1699,18 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
1699
1699
|
function isValidElement(object) {
|
|
1700
1700
|
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
|
|
1701
1701
|
}
|
|
1702
|
-
var
|
|
1702
|
+
var React4 = require_react(), REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = /* @__PURE__ */ Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo"), REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = /* @__PURE__ */ Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for("react.client.reference"), ReactSharedInternals = React4.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
|
|
1703
1703
|
return null;
|
|
1704
1704
|
};
|
|
1705
|
-
|
|
1705
|
+
React4 = {
|
|
1706
1706
|
react_stack_bottom_frame: function(callStackForError) {
|
|
1707
1707
|
return callStackForError();
|
|
1708
1708
|
}
|
|
1709
1709
|
};
|
|
1710
1710
|
var specialPropKeyWarningShown;
|
|
1711
1711
|
var didWarnAboutElementRef = {};
|
|
1712
|
-
var unknownOwnerDebugStack =
|
|
1713
|
-
|
|
1712
|
+
var unknownOwnerDebugStack = React4.react_stack_bottom_frame.bind(
|
|
1713
|
+
React4,
|
|
1714
1714
|
UnknownOwner
|
|
1715
1715
|
)();
|
|
1716
1716
|
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
|
|
@@ -1757,13 +1757,15 @@ var require_jsx_runtime = __commonJS({
|
|
|
1757
1757
|
// src/index.ts
|
|
1758
1758
|
var index_exports = {};
|
|
1759
1759
|
__export(index_exports, {
|
|
1760
|
+
AuthGuard: () => AuthGuard_default,
|
|
1761
|
+
RoleGuard: () => RoleGuard_default,
|
|
1762
|
+
createAppAuth: () => createAppAuth,
|
|
1760
1763
|
createAuthContext: () => createAuthContext
|
|
1761
1764
|
});
|
|
1762
1765
|
module.exports = __toCommonJS(index_exports);
|
|
1763
1766
|
|
|
1764
1767
|
// src/AuthProvider.tsx
|
|
1765
1768
|
var import_react = __toESM(require_react());
|
|
1766
|
-
var import_react_token_manager = require("react-token-manager");
|
|
1767
1769
|
|
|
1768
1770
|
// store/useGuardStore.ts
|
|
1769
1771
|
var import_zustand = require("zustand");
|
|
@@ -1789,39 +1791,16 @@ var import_jsx_runtime = __toESM(require_jsx_runtime());
|
|
|
1789
1791
|
function createAuthContext(options) {
|
|
1790
1792
|
const AuthContext = (0, import_react.createContext)(null);
|
|
1791
1793
|
const AuthProvider = ({ children }) => {
|
|
1792
|
-
const storageType = options?.storage || "cookie";
|
|
1793
|
-
(0, import_react.useEffect)(() => {
|
|
1794
|
-
(0, import_react_token_manager.configureTokenManager)({ storage: storageType });
|
|
1795
|
-
}, [storageType]);
|
|
1796
|
-
const manager = (0, import_react_token_manager.useTokenManager)();
|
|
1797
1794
|
const [loading, setLoading] = (0, import_react.useState)(true);
|
|
1798
1795
|
const rawUser = useAuthStore((state) => state.user);
|
|
1799
1796
|
const error = useAuthStore((state) => state.error);
|
|
1800
1797
|
const user = rawUser;
|
|
1801
|
-
(0, import_react.useEffect)(() => {
|
|
1802
|
-
const savedUser = manager.getSingleToken("user");
|
|
1803
|
-
if (savedUser) {
|
|
1804
|
-
try {
|
|
1805
|
-
const parsedUser = JSON.parse(savedUser);
|
|
1806
|
-
useAuthStore.getState().setUser(parsedUser);
|
|
1807
|
-
useAuthStore.getState().setError(null);
|
|
1808
|
-
} catch {
|
|
1809
|
-
useAuthStore.getState().resetAuth();
|
|
1810
|
-
useAuthStore.getState().setError(
|
|
1811
|
-
new Error("Failed to parse saved user")
|
|
1812
|
-
);
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
setLoading(false);
|
|
1816
|
-
}, [manager]);
|
|
1817
1798
|
const setUser = (userData) => {
|
|
1818
1799
|
useAuthStore.getState().setUser(userData);
|
|
1819
1800
|
useAuthStore.getState().setError(null);
|
|
1820
|
-
manager.setTokens({ user: JSON.stringify(userData) });
|
|
1821
1801
|
};
|
|
1822
1802
|
const login = (tokens, userData) => {
|
|
1823
1803
|
try {
|
|
1824
|
-
manager.setTokens(tokens);
|
|
1825
1804
|
setUser(userData);
|
|
1826
1805
|
} catch (err) {
|
|
1827
1806
|
useAuthStore.getState().setError(
|
|
@@ -1831,7 +1810,6 @@ function createAuthContext(options) {
|
|
|
1831
1810
|
};
|
|
1832
1811
|
const logout = () => {
|
|
1833
1812
|
try {
|
|
1834
|
-
manager.clearTokens();
|
|
1835
1813
|
useAuthStore.getState().resetAuth();
|
|
1836
1814
|
} catch (err) {
|
|
1837
1815
|
useAuthStore.getState().setError(
|
|
@@ -1854,8 +1832,101 @@ function createAuthContext(options) {
|
|
|
1854
1832
|
};
|
|
1855
1833
|
return { AuthProvider, useAuth };
|
|
1856
1834
|
}
|
|
1835
|
+
|
|
1836
|
+
// src/AuthGuard.tsx
|
|
1837
|
+
var import_react2 = __toESM(require_react());
|
|
1838
|
+
var import_navigation = require("next/navigation");
|
|
1839
|
+
var import_react_token_manager = require("react-token-manager");
|
|
1840
|
+
var import_jsx_runtime2 = __toESM(require_jsx_runtime());
|
|
1841
|
+
var AuthGuard = ({
|
|
1842
|
+
children,
|
|
1843
|
+
redirectTo = "/login",
|
|
1844
|
+
tokenKey = "access_token",
|
|
1845
|
+
refreshToken
|
|
1846
|
+
}) => {
|
|
1847
|
+
const manager = (0, import_react_token_manager.useTokenManager)();
|
|
1848
|
+
const router = (0, import_navigation.useRouter)();
|
|
1849
|
+
const isAuthChecked = useAuthStore((state) => state.isAuthChecked);
|
|
1850
|
+
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
|
1851
|
+
const error = useAuthStore((state) => state.error);
|
|
1852
|
+
(0, import_react2.useEffect)(() => {
|
|
1853
|
+
const checkAuth = async () => {
|
|
1854
|
+
try {
|
|
1855
|
+
let token = manager.getSingleToken(tokenKey);
|
|
1856
|
+
if (!token || manager.isExpired(token)) {
|
|
1857
|
+
if (refreshToken) {
|
|
1858
|
+
const newToken = await refreshToken();
|
|
1859
|
+
if (newToken) {
|
|
1860
|
+
manager.setTokens({ [tokenKey]: newToken });
|
|
1861
|
+
token = newToken;
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
const isValid = token && !manager.isExpired(token);
|
|
1866
|
+
useAuthStore.getState().setAuth(Boolean(isValid));
|
|
1867
|
+
if (!isValid) {
|
|
1868
|
+
router.replace(redirectTo);
|
|
1869
|
+
}
|
|
1870
|
+
} catch (err) {
|
|
1871
|
+
useAuthStore.getState().setError(err instanceof Error ? err : new Error(String(err)));
|
|
1872
|
+
useAuthStore.getState().setAuth(false);
|
|
1873
|
+
router.replace(redirectTo);
|
|
1874
|
+
} finally {
|
|
1875
|
+
useAuthStore.getState().setAuthChecked(true);
|
|
1876
|
+
}
|
|
1877
|
+
};
|
|
1878
|
+
checkAuth();
|
|
1879
|
+
}, [manager, router, redirectTo, tokenKey, refreshToken]);
|
|
1880
|
+
if (!isAuthChecked) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: "Loading..." });
|
|
1881
|
+
if (error) return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
1882
|
+
"Error: ",
|
|
1883
|
+
error.message
|
|
1884
|
+
] });
|
|
1885
|
+
if (!isAuthenticated) return null;
|
|
1886
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
|
|
1887
|
+
};
|
|
1888
|
+
var AuthGuard_default = AuthGuard;
|
|
1889
|
+
|
|
1890
|
+
// src/RoleGuard.tsx
|
|
1891
|
+
var import_react3 = __toESM(require_react());
|
|
1892
|
+
var import_navigation2 = require("next/navigation");
|
|
1893
|
+
|
|
1894
|
+
// src/myAuth.ts
|
|
1895
|
+
var auth = createAppAuth();
|
|
1896
|
+
|
|
1897
|
+
// src/RoleGuard.tsx
|
|
1898
|
+
var import_jsx_runtime3 = __toESM(require_jsx_runtime());
|
|
1899
|
+
var RoleGuard = ({
|
|
1900
|
+
children,
|
|
1901
|
+
allowedRoles,
|
|
1902
|
+
redirectTo = "/unauthorized"
|
|
1903
|
+
}) => {
|
|
1904
|
+
const { useAuth } = auth;
|
|
1905
|
+
const { user, loading } = useAuth();
|
|
1906
|
+
const router = (0, import_navigation2.useRouter)();
|
|
1907
|
+
const [isChecking, setIsChecking] = (0, import_react3.useState)(true);
|
|
1908
|
+
(0, import_react3.useEffect)(() => {
|
|
1909
|
+
if (!user) return;
|
|
1910
|
+
const hasAccess = allowedRoles.includes(user?.role);
|
|
1911
|
+
if (!hasAccess) {
|
|
1912
|
+
router.replace(redirectTo);
|
|
1913
|
+
}
|
|
1914
|
+
setIsChecking(false);
|
|
1915
|
+
}, [user, allowedRoles, redirectTo, router]);
|
|
1916
|
+
if (loading || !user || isChecking) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: "Loading..." });
|
|
1917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children });
|
|
1918
|
+
};
|
|
1919
|
+
var RoleGuard_default = RoleGuard;
|
|
1920
|
+
|
|
1921
|
+
// src/index.ts
|
|
1922
|
+
function createAppAuth(storage = "cookie") {
|
|
1923
|
+
return createAuthContext({ storage });
|
|
1924
|
+
}
|
|
1857
1925
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1858
1926
|
0 && (module.exports = {
|
|
1927
|
+
AuthGuard,
|
|
1928
|
+
RoleGuard,
|
|
1929
|
+
createAppAuth,
|
|
1859
1930
|
createAuthContext
|
|
1860
1931
|
});
|
|
1861
1932
|
/*! Bundled license information:
|
package/dist/index.mjs
CHANGED
|
@@ -1693,18 +1693,18 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
1693
1693
|
function isValidElement(object) {
|
|
1694
1694
|
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
|
|
1695
1695
|
}
|
|
1696
|
-
var
|
|
1696
|
+
var React4 = require_react(), REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = /* @__PURE__ */ Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo"), REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = /* @__PURE__ */ Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for("react.client.reference"), ReactSharedInternals = React4.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
|
|
1697
1697
|
return null;
|
|
1698
1698
|
};
|
|
1699
|
-
|
|
1699
|
+
React4 = {
|
|
1700
1700
|
react_stack_bottom_frame: function(callStackForError) {
|
|
1701
1701
|
return callStackForError();
|
|
1702
1702
|
}
|
|
1703
1703
|
};
|
|
1704
1704
|
var specialPropKeyWarningShown;
|
|
1705
1705
|
var didWarnAboutElementRef = {};
|
|
1706
|
-
var unknownOwnerDebugStack =
|
|
1707
|
-
|
|
1706
|
+
var unknownOwnerDebugStack = React4.react_stack_bottom_frame.bind(
|
|
1707
|
+
React4,
|
|
1708
1708
|
UnknownOwner
|
|
1709
1709
|
)();
|
|
1710
1710
|
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
|
|
@@ -1750,7 +1750,6 @@ var require_jsx_runtime = __commonJS({
|
|
|
1750
1750
|
|
|
1751
1751
|
// src/AuthProvider.tsx
|
|
1752
1752
|
var import_react = __toESM(require_react());
|
|
1753
|
-
import { configureTokenManager, useTokenManager } from "react-token-manager";
|
|
1754
1753
|
|
|
1755
1754
|
// store/useGuardStore.ts
|
|
1756
1755
|
import { create } from "zustand";
|
|
@@ -1776,39 +1775,16 @@ var import_jsx_runtime = __toESM(require_jsx_runtime());
|
|
|
1776
1775
|
function createAuthContext(options) {
|
|
1777
1776
|
const AuthContext = (0, import_react.createContext)(null);
|
|
1778
1777
|
const AuthProvider = ({ children }) => {
|
|
1779
|
-
const storageType = options?.storage || "cookie";
|
|
1780
|
-
(0, import_react.useEffect)(() => {
|
|
1781
|
-
configureTokenManager({ storage: storageType });
|
|
1782
|
-
}, [storageType]);
|
|
1783
|
-
const manager = useTokenManager();
|
|
1784
1778
|
const [loading, setLoading] = (0, import_react.useState)(true);
|
|
1785
1779
|
const rawUser = useAuthStore((state) => state.user);
|
|
1786
1780
|
const error = useAuthStore((state) => state.error);
|
|
1787
1781
|
const user = rawUser;
|
|
1788
|
-
(0, import_react.useEffect)(() => {
|
|
1789
|
-
const savedUser = manager.getSingleToken("user");
|
|
1790
|
-
if (savedUser) {
|
|
1791
|
-
try {
|
|
1792
|
-
const parsedUser = JSON.parse(savedUser);
|
|
1793
|
-
useAuthStore.getState().setUser(parsedUser);
|
|
1794
|
-
useAuthStore.getState().setError(null);
|
|
1795
|
-
} catch {
|
|
1796
|
-
useAuthStore.getState().resetAuth();
|
|
1797
|
-
useAuthStore.getState().setError(
|
|
1798
|
-
new Error("Failed to parse saved user")
|
|
1799
|
-
);
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
setLoading(false);
|
|
1803
|
-
}, [manager]);
|
|
1804
1782
|
const setUser = (userData) => {
|
|
1805
1783
|
useAuthStore.getState().setUser(userData);
|
|
1806
1784
|
useAuthStore.getState().setError(null);
|
|
1807
|
-
manager.setTokens({ user: JSON.stringify(userData) });
|
|
1808
1785
|
};
|
|
1809
1786
|
const login = (tokens, userData) => {
|
|
1810
1787
|
try {
|
|
1811
|
-
manager.setTokens(tokens);
|
|
1812
1788
|
setUser(userData);
|
|
1813
1789
|
} catch (err) {
|
|
1814
1790
|
useAuthStore.getState().setError(
|
|
@@ -1818,7 +1794,6 @@ function createAuthContext(options) {
|
|
|
1818
1794
|
};
|
|
1819
1795
|
const logout = () => {
|
|
1820
1796
|
try {
|
|
1821
|
-
manager.clearTokens();
|
|
1822
1797
|
useAuthStore.getState().resetAuth();
|
|
1823
1798
|
} catch (err) {
|
|
1824
1799
|
useAuthStore.getState().setError(
|
|
@@ -1841,7 +1816,100 @@ function createAuthContext(options) {
|
|
|
1841
1816
|
};
|
|
1842
1817
|
return { AuthProvider, useAuth };
|
|
1843
1818
|
}
|
|
1819
|
+
|
|
1820
|
+
// src/AuthGuard.tsx
|
|
1821
|
+
var import_react2 = __toESM(require_react());
|
|
1822
|
+
import { useRouter } from "next/navigation";
|
|
1823
|
+
import { useTokenManager } from "react-token-manager";
|
|
1824
|
+
var import_jsx_runtime2 = __toESM(require_jsx_runtime());
|
|
1825
|
+
var AuthGuard = ({
|
|
1826
|
+
children,
|
|
1827
|
+
redirectTo = "/login",
|
|
1828
|
+
tokenKey = "access_token",
|
|
1829
|
+
refreshToken
|
|
1830
|
+
}) => {
|
|
1831
|
+
const manager = useTokenManager();
|
|
1832
|
+
const router = useRouter();
|
|
1833
|
+
const isAuthChecked = useAuthStore((state) => state.isAuthChecked);
|
|
1834
|
+
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
|
1835
|
+
const error = useAuthStore((state) => state.error);
|
|
1836
|
+
(0, import_react2.useEffect)(() => {
|
|
1837
|
+
const checkAuth = async () => {
|
|
1838
|
+
try {
|
|
1839
|
+
let token = manager.getSingleToken(tokenKey);
|
|
1840
|
+
if (!token || manager.isExpired(token)) {
|
|
1841
|
+
if (refreshToken) {
|
|
1842
|
+
const newToken = await refreshToken();
|
|
1843
|
+
if (newToken) {
|
|
1844
|
+
manager.setTokens({ [tokenKey]: newToken });
|
|
1845
|
+
token = newToken;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
const isValid = token && !manager.isExpired(token);
|
|
1850
|
+
useAuthStore.getState().setAuth(Boolean(isValid));
|
|
1851
|
+
if (!isValid) {
|
|
1852
|
+
router.replace(redirectTo);
|
|
1853
|
+
}
|
|
1854
|
+
} catch (err) {
|
|
1855
|
+
useAuthStore.getState().setError(err instanceof Error ? err : new Error(String(err)));
|
|
1856
|
+
useAuthStore.getState().setAuth(false);
|
|
1857
|
+
router.replace(redirectTo);
|
|
1858
|
+
} finally {
|
|
1859
|
+
useAuthStore.getState().setAuthChecked(true);
|
|
1860
|
+
}
|
|
1861
|
+
};
|
|
1862
|
+
checkAuth();
|
|
1863
|
+
}, [manager, router, redirectTo, tokenKey, refreshToken]);
|
|
1864
|
+
if (!isAuthChecked) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: "Loading..." });
|
|
1865
|
+
if (error) return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
1866
|
+
"Error: ",
|
|
1867
|
+
error.message
|
|
1868
|
+
] });
|
|
1869
|
+
if (!isAuthenticated) return null;
|
|
1870
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
|
|
1871
|
+
};
|
|
1872
|
+
var AuthGuard_default = AuthGuard;
|
|
1873
|
+
|
|
1874
|
+
// src/RoleGuard.tsx
|
|
1875
|
+
var import_react3 = __toESM(require_react());
|
|
1876
|
+
import { useRouter as useRouter2 } from "next/navigation";
|
|
1877
|
+
|
|
1878
|
+
// src/myAuth.ts
|
|
1879
|
+
var auth = createAppAuth();
|
|
1880
|
+
|
|
1881
|
+
// src/RoleGuard.tsx
|
|
1882
|
+
var import_jsx_runtime3 = __toESM(require_jsx_runtime());
|
|
1883
|
+
var RoleGuard = ({
|
|
1884
|
+
children,
|
|
1885
|
+
allowedRoles,
|
|
1886
|
+
redirectTo = "/unauthorized"
|
|
1887
|
+
}) => {
|
|
1888
|
+
const { useAuth } = auth;
|
|
1889
|
+
const { user, loading } = useAuth();
|
|
1890
|
+
const router = useRouter2();
|
|
1891
|
+
const [isChecking, setIsChecking] = (0, import_react3.useState)(true);
|
|
1892
|
+
(0, import_react3.useEffect)(() => {
|
|
1893
|
+
if (!user) return;
|
|
1894
|
+
const hasAccess = allowedRoles.includes(user?.role);
|
|
1895
|
+
if (!hasAccess) {
|
|
1896
|
+
router.replace(redirectTo);
|
|
1897
|
+
}
|
|
1898
|
+
setIsChecking(false);
|
|
1899
|
+
}, [user, allowedRoles, redirectTo, router]);
|
|
1900
|
+
if (loading || !user || isChecking) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: "Loading..." });
|
|
1901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children });
|
|
1902
|
+
};
|
|
1903
|
+
var RoleGuard_default = RoleGuard;
|
|
1904
|
+
|
|
1905
|
+
// src/index.ts
|
|
1906
|
+
function createAppAuth(storage = "cookie") {
|
|
1907
|
+
return createAuthContext({ storage });
|
|
1908
|
+
}
|
|
1844
1909
|
export {
|
|
1910
|
+
AuthGuard_default as AuthGuard,
|
|
1911
|
+
RoleGuard_default as RoleGuard,
|
|
1912
|
+
createAppAuth,
|
|
1845
1913
|
createAuthContext
|
|
1846
1914
|
};
|
|
1847
1915
|
/*! Bundled license information:
|
package/package.json
CHANGED
package/src/AuthGuard.tsx
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import React, { useEffect, useState } from 'react'
|
|
4
|
+
import { useRouter } from 'next/navigation'
|
|
5
|
+
import { useTokenManager } from 'react-token-manager'
|
|
6
|
+
import { useAuthStore } from '../store/useGuardStore'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
type AuthGuardProps = {
|
|
9
|
+
children: React.ReactNode
|
|
10
|
+
redirectTo?: string
|
|
11
|
+
tokenKey?: string
|
|
12
|
+
refreshToken?: () => Promise<string | null>
|
|
13
|
+
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
const AuthGuard = ({
|
|
16
|
+
children,
|
|
17
|
+
redirectTo = '/login',
|
|
18
|
+
tokenKey = 'access_token',
|
|
19
|
+
refreshToken,
|
|
20
|
+
}: AuthGuardProps) => {
|
|
21
|
+
const manager = useTokenManager()
|
|
22
|
+
const router = useRouter()
|
|
23
|
+
const isAuthChecked = useAuthStore((state) => state.isAuthChecked)
|
|
24
|
+
const isAuthenticated = useAuthStore((state) => state.isAuthenticated)
|
|
25
|
+
const error = useAuthStore((state) => state.error)
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const checkAuth = async () => {
|
|
29
|
+
try {
|
|
30
|
+
let token = manager.getSingleToken(tokenKey)
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
if (!token || manager.isExpired(token)) {
|
|
33
|
+
if (refreshToken) {
|
|
34
|
+
const newToken = await refreshToken()
|
|
35
|
+
if (newToken) {
|
|
36
|
+
manager.setTokens({ [tokenKey]: newToken })
|
|
37
|
+
token = newToken
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const isValid = token && !manager.isExpired(token)
|
|
43
|
+
useAuthStore.getState().setAuth(Boolean(isValid))
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
if (!isValid) {
|
|
46
|
+
router.replace(redirectTo)
|
|
47
|
+
}
|
|
48
|
+
} catch (err: any) {
|
|
49
|
+
useAuthStore.getState().setError(err instanceof Error ? err : new Error(String(err)))
|
|
50
|
+
useAuthStore.getState().setAuth(false)
|
|
51
|
+
router.replace(redirectTo)
|
|
52
|
+
} finally {
|
|
53
|
+
useAuthStore.getState().setAuthChecked(true)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
checkAuth()
|
|
58
|
+
}, [manager, router, redirectTo, tokenKey, refreshToken])
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
if (!isAuthChecked) return <div>Loading...</div>
|
|
61
|
+
if (error) return <div>Error: {error.message}</div>
|
|
62
|
+
if (!isAuthenticated) return null
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
return <>{children}</>
|
|
65
|
+
}
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
export default AuthGuard
|
package/src/AuthProvider.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import React, {
|
|
|
7
7
|
useEffect,
|
|
8
8
|
useState,
|
|
9
9
|
} from 'react'
|
|
10
|
-
import { configureTokenManager, useTokenManager } from 'react-token-manager'
|
|
10
|
+
// import { configureTokenManager, useTokenManager } from 'react-token-manager'
|
|
11
11
|
import { useAuthStore } from '../store/useGuardStore'
|
|
12
12
|
|
|
13
13
|
export type AuthContextType<UserType> = {
|
|
@@ -30,15 +30,15 @@ export function createAuthContext<UserType>(options?: AuthContextOptions) {
|
|
|
30
30
|
const AuthContext = createContext<AuthContextType<UserType> | null>(null)
|
|
31
31
|
|
|
32
32
|
const AuthProvider = ({ children }: { children: ReactNode }) => {
|
|
33
|
-
const storageType = options?.storage || 'cookie'
|
|
33
|
+
// const storageType = options?.storage || 'cookie'
|
|
34
34
|
|
|
35
35
|
// Configure token manager once on mount
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
|
|
38
|
-
}, [storageType])
|
|
36
|
+
// useEffect(() => {
|
|
37
|
+
// configureTokenManager({ storage: storageType })
|
|
38
|
+
// }, [storageType])
|
|
39
39
|
|
|
40
40
|
// ✅ Hooks must be called inside component
|
|
41
|
-
const manager = useTokenManager()
|
|
41
|
+
// const manager = useTokenManager()
|
|
42
42
|
|
|
43
43
|
const [loading, setLoading] = useState(true)
|
|
44
44
|
|
|
@@ -47,32 +47,32 @@ export function createAuthContext<UserType>(options?: AuthContextOptions) {
|
|
|
47
47
|
const user = rawUser as UserType | null
|
|
48
48
|
|
|
49
49
|
// Restore saved user from token manager
|
|
50
|
-
useEffect(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}, [manager])
|
|
50
|
+
// useEffect(() => {
|
|
51
|
+
// const savedUser = manager.getSingleToken('user')
|
|
52
|
+
// if (savedUser) {
|
|
53
|
+
// try {
|
|
54
|
+
// const parsedUser = JSON.parse(savedUser)
|
|
55
|
+
// useAuthStore.getState().setUser(parsedUser)
|
|
56
|
+
// useAuthStore.getState().setError(null)
|
|
57
|
+
// } catch {
|
|
58
|
+
// useAuthStore.getState().resetAuth()
|
|
59
|
+
// useAuthStore.getState().setError(
|
|
60
|
+
// new Error('Failed to parse saved user')
|
|
61
|
+
// )
|
|
62
|
+
// }
|
|
63
|
+
// }
|
|
64
|
+
// setLoading(false)
|
|
65
|
+
// }, [manager])
|
|
66
66
|
|
|
67
67
|
const setUser = (userData: UserType) => {
|
|
68
68
|
useAuthStore.getState().setUser(userData as any)
|
|
69
69
|
useAuthStore.getState().setError(null)
|
|
70
|
-
manager.setTokens({ user: JSON.stringify(userData) })
|
|
70
|
+
// manager.setTokens({ user: JSON.stringify(userData) })
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const login = (tokens: Record<string, string>, userData: UserType) => {
|
|
74
74
|
try {
|
|
75
|
-
manager.setTokens(tokens)
|
|
75
|
+
// manager.setTokens(tokens)
|
|
76
76
|
setUser(userData)
|
|
77
77
|
} catch (err) {
|
|
78
78
|
useAuthStore.getState().setError(
|
|
@@ -83,7 +83,7 @@ export function createAuthContext<UserType>(options?: AuthContextOptions) {
|
|
|
83
83
|
|
|
84
84
|
const logout = () => {
|
|
85
85
|
try {
|
|
86
|
-
manager.clearTokens()
|
|
86
|
+
// manager.clearTokens()
|
|
87
87
|
useAuthStore.getState().resetAuth()
|
|
88
88
|
} catch (err) {
|
|
89
89
|
useAuthStore.getState().setError(
|
package/src/RoleGuard.tsx
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useState } from 'react'
|
|
4
|
+
import { useRouter } from 'next/navigation'
|
|
5
|
+
import { auth } from './myAuth'
|
|
6
|
+
|
|
7
|
+
type RoleGuardProps = {
|
|
8
|
+
children: React.ReactNode
|
|
9
|
+
allowedRoles: string[]
|
|
10
|
+
redirectTo?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const RoleGuard: React.FC<RoleGuardProps> = ({
|
|
14
|
+
children,
|
|
15
|
+
allowedRoles,
|
|
16
|
+
redirectTo = '/unauthorized',
|
|
17
|
+
}) => {
|
|
18
|
+
// ✅ Destructure useAuth INSIDE the component
|
|
19
|
+
const { useAuth } = auth
|
|
20
|
+
const { user, loading } = useAuth()
|
|
21
|
+
|
|
22
|
+
const router = useRouter()
|
|
23
|
+
const [isChecking, setIsChecking] = useState(true)
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!user) return
|
|
27
|
+
|
|
28
|
+
const hasAccess = allowedRoles.includes(user?.role)
|
|
29
|
+
if (!hasAccess) {
|
|
30
|
+
router.replace(redirectTo)
|
|
31
|
+
}
|
|
32
|
+
setIsChecking(false)
|
|
33
|
+
}, [user, allowedRoles, redirectTo, router])
|
|
34
|
+
|
|
35
|
+
if (loading || !user || isChecking) return <div>Loading...</div>
|
|
36
|
+
|
|
37
|
+
return <>{children}</>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default RoleGuard
|
package/src/index.ts
CHANGED
|
@@ -5,12 +5,12 @@ export type User = {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
// Export factory instead of fixed instance
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
export function createAppAuth(
|
|
9
|
+
storage: 'localStorage' | 'sessionStorage' | 'cookie' = 'cookie'
|
|
10
|
+
) {
|
|
11
|
+
return createAuthContext<User>({ storage })
|
|
12
|
+
}
|
|
13
13
|
|
|
14
14
|
export { createAuthContext } from './AuthProvider'
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
export { default as AuthGuard } from './AuthGuard'
|
|
16
|
+
export { default as RoleGuard } from './RoleGuard'
|
package/src/myAuth.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// myAuth.ts
|
|
2
|
+
'use client'
|
|
3
|
+
import { createAppAuth } from '.'
|
|
4
|
+
export const auth = createAppAuth() // { AuthProvider, useAuth }
|