@meet_patel_03/authflow-react 0.1.0 → 0.1.2
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.js +34 -58
- package/package.json +13 -9
- package/dist/index.d.mts +0 -84
- package/dist/index.mjs +0 -127
package/dist/index.js
CHANGED
|
@@ -1,51 +1,28 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
AuthFlowProvider: () => AuthFlowProvider,
|
|
24
|
-
useAuthCallback: () => useAuthCallback,
|
|
25
|
-
useAuthFlow: () => useAuthFlow,
|
|
26
|
-
useUser: () => useUser,
|
|
27
|
-
withAuthRequired: () => withAuthRequired
|
|
28
|
-
});
|
|
29
|
-
module.exports = __toCommonJS(index_exports);
|
|
30
|
-
|
|
31
1
|
// src/AuthFlowContext.tsx
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
2
|
+
import {
|
|
3
|
+
createContext,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useEffect,
|
|
7
|
+
useRef,
|
|
8
|
+
useState
|
|
9
|
+
} from "react";
|
|
10
|
+
import { AuthFlowClient } from "@meet_patel_03/authflow-js";
|
|
11
|
+
import { jsx } from "react/jsx-runtime";
|
|
12
|
+
var AuthFlowContext = createContext(null);
|
|
36
13
|
var AuthFlowProvider = ({
|
|
37
14
|
config,
|
|
38
15
|
children
|
|
39
16
|
}) => {
|
|
40
|
-
const clientRef =
|
|
17
|
+
const clientRef = useRef(null);
|
|
41
18
|
if (!clientRef.current) {
|
|
42
|
-
clientRef.current = new
|
|
19
|
+
clientRef.current = new AuthFlowClient(config);
|
|
43
20
|
}
|
|
44
21
|
const client = clientRef.current;
|
|
45
|
-
const [user, setUser] =
|
|
46
|
-
const [isLoading, setIsLoading] =
|
|
47
|
-
const [isAuthenticated, setIsAuthenticated] =
|
|
48
|
-
|
|
22
|
+
const [user, setUser] = useState(null);
|
|
23
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
24
|
+
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
25
|
+
useEffect(() => {
|
|
49
26
|
const initAuth = async () => {
|
|
50
27
|
try {
|
|
51
28
|
const token = await client.getAccessToken();
|
|
@@ -61,18 +38,18 @@ var AuthFlowProvider = ({
|
|
|
61
38
|
};
|
|
62
39
|
initAuth();
|
|
63
40
|
}, [client]);
|
|
64
|
-
const loginWithRedirect =
|
|
41
|
+
const loginWithRedirect = useCallback(
|
|
65
42
|
(options) => client.loginWithRedirect(options),
|
|
66
43
|
[client]
|
|
67
44
|
);
|
|
68
|
-
const handleRedirectCallback =
|
|
45
|
+
const handleRedirectCallback = useCallback(async () => {
|
|
69
46
|
const tokens = await client.handleRedirectCallback();
|
|
70
47
|
setUser(client.getUser());
|
|
71
48
|
setIsAuthenticated(true);
|
|
72
49
|
return tokens;
|
|
73
50
|
}, [client]);
|
|
74
|
-
const getAccessToken =
|
|
75
|
-
const logout =
|
|
51
|
+
const getAccessToken = useCallback(() => client.getAccessToken(), [client]);
|
|
52
|
+
const logout = useCallback(
|
|
76
53
|
async (options) => {
|
|
77
54
|
await client.logout(options);
|
|
78
55
|
setUser(null);
|
|
@@ -90,10 +67,10 @@ var AuthFlowProvider = ({
|
|
|
90
67
|
getAccessToken,
|
|
91
68
|
logout
|
|
92
69
|
};
|
|
93
|
-
return /* @__PURE__ */
|
|
70
|
+
return /* @__PURE__ */ jsx(AuthFlowContext.Provider, { value, children });
|
|
94
71
|
};
|
|
95
72
|
var useAuthFlow = () => {
|
|
96
|
-
const ctx =
|
|
73
|
+
const ctx = useContext(AuthFlowContext);
|
|
97
74
|
if (!ctx) {
|
|
98
75
|
throw new Error(
|
|
99
76
|
"useAuthFlow must be used inside <AuthFlowProvider>. Wrap your app: <AuthFlowProvider config={...}><App /></AuthFlowProvider>"
|
|
@@ -106,34 +83,34 @@ function withAuthRequired(Component, options = {}) {
|
|
|
106
83
|
const displayName = Component.displayName ?? Component.name ?? "Component";
|
|
107
84
|
const WithAuthRequired = (props) => {
|
|
108
85
|
const { isAuthenticated, isLoading, loginWithRedirect } = useAuthFlow();
|
|
109
|
-
|
|
86
|
+
useEffect(() => {
|
|
110
87
|
if (!isLoading && !isAuthenticated) {
|
|
111
88
|
loginWithRedirect();
|
|
112
89
|
}
|
|
113
90
|
}, [isLoading, isAuthenticated, loginWithRedirect]);
|
|
114
91
|
if (isLoading || !isAuthenticated) return null;
|
|
115
|
-
return /* @__PURE__ */
|
|
92
|
+
return /* @__PURE__ */ jsx(Component, { ...props });
|
|
116
93
|
};
|
|
117
94
|
WithAuthRequired.displayName = `withAuthRequired(${displayName})`;
|
|
118
95
|
return WithAuthRequired;
|
|
119
96
|
}
|
|
120
97
|
|
|
121
98
|
// src/useAuthCallback.ts
|
|
122
|
-
|
|
123
|
-
|
|
99
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
100
|
+
import { AuthFlowError } from "@meet_patel_03/authflow-js";
|
|
124
101
|
var useAuthCallback = (options = {}) => {
|
|
125
102
|
const { handleRedirectCallback } = useAuthFlow();
|
|
126
|
-
const [status, setStatus] = (
|
|
127
|
-
const [error, setError] = (
|
|
128
|
-
const hasRun = (
|
|
129
|
-
(
|
|
103
|
+
const [status, setStatus] = useState2("loading");
|
|
104
|
+
const [error, setError] = useState2(null);
|
|
105
|
+
const hasRun = useRef2(false);
|
|
106
|
+
useEffect2(() => {
|
|
130
107
|
if (hasRun.current) return;
|
|
131
108
|
hasRun.current = true;
|
|
132
109
|
handleRedirectCallback().then(() => {
|
|
133
110
|
setStatus("success");
|
|
134
111
|
options.onSuccess?.();
|
|
135
112
|
}).catch((err) => {
|
|
136
|
-
const message = err instanceof
|
|
113
|
+
const message = err instanceof AuthFlowError ? err.errorDescription ?? err.error : err instanceof Error ? err.message : "Unknown error during login callback.";
|
|
137
114
|
setStatus("error");
|
|
138
115
|
setError(message);
|
|
139
116
|
options.onError?.(message);
|
|
@@ -141,11 +118,10 @@ var useAuthCallback = (options = {}) => {
|
|
|
141
118
|
}, []);
|
|
142
119
|
return { status, error };
|
|
143
120
|
};
|
|
144
|
-
|
|
145
|
-
0 && (module.exports = {
|
|
121
|
+
export {
|
|
146
122
|
AuthFlowProvider,
|
|
147
123
|
useAuthCallback,
|
|
148
124
|
useAuthFlow,
|
|
149
125
|
useUser,
|
|
150
126
|
withAuthRequired
|
|
151
|
-
}
|
|
127
|
+
};
|
package/package.json
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meet_patel_03/authflow-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "AuthFlow React SDK — hooks and provider for the Authorization Code + PKCE flow",
|
|
5
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
6
7
|
"module": "./dist/index.js",
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"types": "./dist/index.d.ts"
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "tsup src/index.ts --format esm
|
|
20
|
-
"dev": "tsup src/index.ts --format esm
|
|
19
|
+
"build": "tsup src/index.ts --format esm --dts --clean --external react,@meet_patel_03/authflow-js",
|
|
20
|
+
"dev": "tsup src/index.ts --format esm --dts --watch --external react,@meet_patel_03/authflow-js",
|
|
21
21
|
"test": "vitest run"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"react": ">=18.0.0",
|
|
25
|
-
"@meet_patel_03/authflow-js": "^0.1.
|
|
25
|
+
"@meet_patel_03/authflow-js": "^0.1.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@testing-library/react": "^14.0.0",
|
|
@@ -43,5 +43,9 @@
|
|
|
43
43
|
],
|
|
44
44
|
"license": "MIT",
|
|
45
45
|
"sideEffects": false,
|
|
46
|
-
"author": "Meet Patel (https://github.com/Meet-Patel-12)"
|
|
46
|
+
"author": "Meet Patel (https://github.com/Meet-Patel-12)",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/Meet-Patel-12/AuthFlow"
|
|
50
|
+
}
|
|
47
51
|
}
|
package/dist/index.d.mts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { AuthFlowClient, AuthFlowUser, TokenSet, AuthFlowConfig } from '@meet_patel_03/authflow-js';
|
|
3
|
-
export { AuthFlowConfig, AuthFlowError, AuthFlowUser, TokenSet } from '@meet_patel_03/authflow-js';
|
|
4
|
-
|
|
5
|
-
interface AuthFlowContextValue {
|
|
6
|
-
/** The underlying AuthFlowClient instance — use this for advanced operations */
|
|
7
|
-
client: AuthFlowClient;
|
|
8
|
-
/** Current authenticated user, null if not logged in */
|
|
9
|
-
user: AuthFlowUser | null;
|
|
10
|
-
/** True once the initial auth state has been resolved */
|
|
11
|
-
isLoading: boolean;
|
|
12
|
-
/** True if the user is logged in and the access token is not expired */
|
|
13
|
-
isAuthenticated: boolean;
|
|
14
|
-
/** Redirect to the AuthFlow Universal Login page */
|
|
15
|
-
loginWithRedirect: (options?: {
|
|
16
|
-
screen_hint?: "login" | "signup";
|
|
17
|
-
}) => Promise<void>;
|
|
18
|
-
/**
|
|
19
|
-
* Call in your /callback route.
|
|
20
|
-
* Exchanges the authorization code for tokens, then resolves with the TokenSet.
|
|
21
|
-
*/
|
|
22
|
-
handleRedirectCallback: () => Promise<TokenSet>;
|
|
23
|
-
/**
|
|
24
|
-
* Returns a valid access token, auto-refreshing if near expiry.
|
|
25
|
-
* Returns null if not authenticated.
|
|
26
|
-
*/
|
|
27
|
-
getAccessToken: () => Promise<string | null>;
|
|
28
|
-
/** Revokes server-side session, clears tokens, and redirects to returnTo */
|
|
29
|
-
logout: (options?: {
|
|
30
|
-
returnTo?: string;
|
|
31
|
-
}) => Promise<void>;
|
|
32
|
-
}
|
|
33
|
-
interface AuthFlowProviderProps {
|
|
34
|
-
/** AuthFlow configuration — same shape as AuthFlowClient constructor */
|
|
35
|
-
config: AuthFlowConfig;
|
|
36
|
-
children: React.ReactNode;
|
|
37
|
-
}
|
|
38
|
-
declare const AuthFlowProvider: React.FC<AuthFlowProviderProps>;
|
|
39
|
-
/**
|
|
40
|
-
* Primary hook — use this in any component to access auth state and actions.
|
|
41
|
-
*
|
|
42
|
-
* @throws if used outside of <AuthFlowProvider>
|
|
43
|
-
*/
|
|
44
|
-
declare const useAuthFlow: () => AuthFlowContextValue;
|
|
45
|
-
/** Convenience hook — returns just the current user */
|
|
46
|
-
declare const useUser: () => AuthFlowUser | null;
|
|
47
|
-
/**
|
|
48
|
-
* HOC that redirects to login if the user is not authenticated.
|
|
49
|
-
* Renders null while auth state is loading.
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* const ProtectedDashboard = withAuthRequired(Dashboard);
|
|
53
|
-
*/
|
|
54
|
-
declare function withAuthRequired<P extends object>(Component: React.ComponentType<P>, options?: {
|
|
55
|
-
returnTo?: string;
|
|
56
|
-
}): React.FC<P>;
|
|
57
|
-
|
|
58
|
-
type CallbackStatus = "loading" | "success" | "error";
|
|
59
|
-
interface UseAuthCallbackResult {
|
|
60
|
-
status: CallbackStatus;
|
|
61
|
-
error: string | null;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Drop this in your /callback route component.
|
|
65
|
-
* Handles the token exchange and calls onSuccess or onError when done.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* function CallbackPage() {
|
|
69
|
-
* const { status, error } = useAuthCallback({
|
|
70
|
-
* onSuccess: () => navigate("/dashboard"),
|
|
71
|
-
* onError: (err) => navigate("/login?error=" + err),
|
|
72
|
-
* });
|
|
73
|
-
*
|
|
74
|
-
* if (status === "loading") return <Spinner />;
|
|
75
|
-
* if (status === "error") return <div>Login failed: {error}</div>;
|
|
76
|
-
* return null;
|
|
77
|
-
* }
|
|
78
|
-
*/
|
|
79
|
-
declare const useAuthCallback: (options?: {
|
|
80
|
-
onSuccess?: () => void;
|
|
81
|
-
onError?: (error: string) => void;
|
|
82
|
-
}) => UseAuthCallbackResult;
|
|
83
|
-
|
|
84
|
-
export { type AuthFlowContextValue, AuthFlowProvider, type AuthFlowProviderProps, type CallbackStatus, type UseAuthCallbackResult, useAuthCallback, useAuthFlow, useUser, withAuthRequired };
|
package/dist/index.mjs
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
// src/AuthFlowContext.tsx
|
|
2
|
-
import {
|
|
3
|
-
createContext,
|
|
4
|
-
useCallback,
|
|
5
|
-
useContext,
|
|
6
|
-
useEffect,
|
|
7
|
-
useRef,
|
|
8
|
-
useState
|
|
9
|
-
} from "react";
|
|
10
|
-
import { AuthFlowClient } from "@meet_patel_03/authflow-js";
|
|
11
|
-
import { jsx } from "react/jsx-runtime";
|
|
12
|
-
var AuthFlowContext = createContext(null);
|
|
13
|
-
var AuthFlowProvider = ({
|
|
14
|
-
config,
|
|
15
|
-
children
|
|
16
|
-
}) => {
|
|
17
|
-
const clientRef = useRef(null);
|
|
18
|
-
if (!clientRef.current) {
|
|
19
|
-
clientRef.current = new AuthFlowClient(config);
|
|
20
|
-
}
|
|
21
|
-
const client = clientRef.current;
|
|
22
|
-
const [user, setUser] = useState(null);
|
|
23
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
24
|
-
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
const initAuth = async () => {
|
|
27
|
-
try {
|
|
28
|
-
const token = await client.getAccessToken();
|
|
29
|
-
if (token) {
|
|
30
|
-
const currentUser = client.getUser();
|
|
31
|
-
setUser(currentUser);
|
|
32
|
-
setIsAuthenticated(true);
|
|
33
|
-
}
|
|
34
|
-
} catch {
|
|
35
|
-
} finally {
|
|
36
|
-
setIsLoading(false);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
initAuth();
|
|
40
|
-
}, [client]);
|
|
41
|
-
const loginWithRedirect = useCallback(
|
|
42
|
-
(options) => client.loginWithRedirect(options),
|
|
43
|
-
[client]
|
|
44
|
-
);
|
|
45
|
-
const handleRedirectCallback = useCallback(async () => {
|
|
46
|
-
const tokens = await client.handleRedirectCallback();
|
|
47
|
-
setUser(client.getUser());
|
|
48
|
-
setIsAuthenticated(true);
|
|
49
|
-
return tokens;
|
|
50
|
-
}, [client]);
|
|
51
|
-
const getAccessToken = useCallback(() => client.getAccessToken(), [client]);
|
|
52
|
-
const logout = useCallback(
|
|
53
|
-
async (options) => {
|
|
54
|
-
await client.logout(options);
|
|
55
|
-
setUser(null);
|
|
56
|
-
setIsAuthenticated(false);
|
|
57
|
-
},
|
|
58
|
-
[client]
|
|
59
|
-
);
|
|
60
|
-
const value = {
|
|
61
|
-
client,
|
|
62
|
-
user,
|
|
63
|
-
isLoading,
|
|
64
|
-
isAuthenticated,
|
|
65
|
-
loginWithRedirect,
|
|
66
|
-
handleRedirectCallback,
|
|
67
|
-
getAccessToken,
|
|
68
|
-
logout
|
|
69
|
-
};
|
|
70
|
-
return /* @__PURE__ */ jsx(AuthFlowContext.Provider, { value, children });
|
|
71
|
-
};
|
|
72
|
-
var useAuthFlow = () => {
|
|
73
|
-
const ctx = useContext(AuthFlowContext);
|
|
74
|
-
if (!ctx) {
|
|
75
|
-
throw new Error(
|
|
76
|
-
"useAuthFlow must be used inside <AuthFlowProvider>. Wrap your app: <AuthFlowProvider config={...}><App /></AuthFlowProvider>"
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
return ctx;
|
|
80
|
-
};
|
|
81
|
-
var useUser = () => useAuthFlow().user;
|
|
82
|
-
function withAuthRequired(Component, options = {}) {
|
|
83
|
-
const displayName = Component.displayName ?? Component.name ?? "Component";
|
|
84
|
-
const WithAuthRequired = (props) => {
|
|
85
|
-
const { isAuthenticated, isLoading, loginWithRedirect } = useAuthFlow();
|
|
86
|
-
useEffect(() => {
|
|
87
|
-
if (!isLoading && !isAuthenticated) {
|
|
88
|
-
loginWithRedirect();
|
|
89
|
-
}
|
|
90
|
-
}, [isLoading, isAuthenticated, loginWithRedirect]);
|
|
91
|
-
if (isLoading || !isAuthenticated) return null;
|
|
92
|
-
return /* @__PURE__ */ jsx(Component, { ...props });
|
|
93
|
-
};
|
|
94
|
-
WithAuthRequired.displayName = `withAuthRequired(${displayName})`;
|
|
95
|
-
return WithAuthRequired;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// src/useAuthCallback.ts
|
|
99
|
-
import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
100
|
-
import { AuthFlowError } from "@meet_patel_03/authflow-js";
|
|
101
|
-
var useAuthCallback = (options = {}) => {
|
|
102
|
-
const { handleRedirectCallback } = useAuthFlow();
|
|
103
|
-
const [status, setStatus] = useState2("loading");
|
|
104
|
-
const [error, setError] = useState2(null);
|
|
105
|
-
const hasRun = useRef2(false);
|
|
106
|
-
useEffect2(() => {
|
|
107
|
-
if (hasRun.current) return;
|
|
108
|
-
hasRun.current = true;
|
|
109
|
-
handleRedirectCallback().then(() => {
|
|
110
|
-
setStatus("success");
|
|
111
|
-
options.onSuccess?.();
|
|
112
|
-
}).catch((err) => {
|
|
113
|
-
const message = err instanceof AuthFlowError ? err.errorDescription ?? err.error : err instanceof Error ? err.message : "Unknown error during login callback.";
|
|
114
|
-
setStatus("error");
|
|
115
|
-
setError(message);
|
|
116
|
-
options.onError?.(message);
|
|
117
|
-
});
|
|
118
|
-
}, []);
|
|
119
|
-
return { status, error };
|
|
120
|
-
};
|
|
121
|
-
export {
|
|
122
|
-
AuthFlowProvider,
|
|
123
|
-
useAuthCallback,
|
|
124
|
-
useAuthFlow,
|
|
125
|
-
useUser,
|
|
126
|
-
withAuthRequired
|
|
127
|
-
};
|