@meshagent/meshagent-react-auth 0.36.3 → 0.37.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/CHANGELOG.md +19 -0
- package/README.md +406 -1
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.js +2 -4
- package/dist/cjs/mauth-response.d.ts +9 -1
- package/dist/cjs/mauth-response.js +75 -35
- package/dist/cjs/reference-key.d.ts +1 -0
- package/dist/cjs/reference-key.js +18 -0
- package/dist/cjs/use-auth.d.ts +35 -0
- package/dist/cjs/use-auth.js +482 -0
- package/dist/cjs/use-ensure-login.d.ts +13 -0
- package/dist/cjs/use-ensure-login.js +29 -0
- package/dist/cjs/use-login-scope.d.ts +4 -14
- package/dist/cjs/use-login-scope.js +5 -222
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/mauth-response.d.ts +9 -1
- package/dist/esm/mauth-response.js +75 -35
- package/dist/esm/reference-key.d.ts +1 -0
- package/dist/esm/reference-key.js +15 -0
- package/dist/esm/use-auth.d.ts +35 -0
- package/dist/esm/use-auth.js +478 -0
- package/dist/esm/use-ensure-login.d.ts +13 -0
- package/dist/esm/use-ensure-login.js +26 -0
- package/dist/esm/use-login-scope.d.ts +4 -14
- package/dist/esm/use-login-scope.js +5 -221
- package/package.json +7 -5
|
@@ -1,223 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return value instanceof URL ? value : new URL(value);
|
|
7
|
-
}
|
|
8
|
-
class UserProfileFetchError extends Error {
|
|
9
|
-
constructor(status, message) {
|
|
10
|
-
super(message);
|
|
11
|
-
Object.defineProperty(this, "status", {
|
|
12
|
-
enumerable: true,
|
|
13
|
-
configurable: true,
|
|
14
|
-
writable: true,
|
|
15
|
-
value: void 0
|
|
16
|
-
});
|
|
17
|
-
this.name = "UserProfileFetchError";
|
|
18
|
-
this.status = status;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function isAuthProfileError(error) {
|
|
22
|
-
return error instanceof UserProfileFetchError
|
|
23
|
-
&& (error.status === 401 || error.status === 403);
|
|
24
|
-
}
|
|
25
|
-
async function fetchUserProfile(params) {
|
|
26
|
-
const response = await fetch(new URL("/accounts/profiles/me", toUrl(params.serverUrl)), {
|
|
27
|
-
signal: params.signal,
|
|
28
|
-
headers: {
|
|
29
|
-
"Authorization": `Bearer ${params.accessToken}`,
|
|
30
|
-
"Accept": "application/json",
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
if (!response.ok) {
|
|
34
|
-
throw new UserProfileFetchError(response.status, `Failed to fetch user profile: ${response.status} ${await response.text()}`);
|
|
35
|
-
}
|
|
36
|
-
return await response.json();
|
|
37
|
-
}
|
|
38
|
-
function serializeExtraQueryParams(extraQueryParams) {
|
|
39
|
-
return JSON.stringify(Object.entries(extraQueryParams ?? {}).sort(([left], [right]) => left.localeCompare(right)));
|
|
40
|
-
}
|
|
41
|
-
export async function buildOAuthAuthorizeUrl(params) {
|
|
42
|
-
const serverUrl = toUrl(params.serverUrl);
|
|
43
|
-
const callbackUrl = toUrl(params.callbackUrl);
|
|
44
|
-
const generator = new PkceGenerator();
|
|
45
|
-
const pair = await generator.generate();
|
|
46
|
-
const cache = new LocalStoragePkceCache(params.storage ?? getDefaultStorage());
|
|
47
|
-
await cache.saveVerifier(pair.codeVerifier);
|
|
48
|
-
const query = new URLSearchParams({
|
|
49
|
-
...(params.extraQueryParams ?? {}),
|
|
50
|
-
scope: params.scope ?? "profile",
|
|
51
|
-
client_id: params.oauthClientId,
|
|
52
|
-
code_challenge: pair.codeChallenge,
|
|
53
|
-
response_type: "code",
|
|
54
|
-
redirect_uri: callbackUrl.toString(),
|
|
55
|
-
prompt: "select_account",
|
|
56
|
-
});
|
|
57
|
-
if (params.provider) {
|
|
58
|
-
query.set("provider", params.provider);
|
|
59
|
-
}
|
|
60
|
-
return new URL(`/oauth/authorize?${query.toString()}`, serverUrl);
|
|
61
|
-
}
|
|
62
|
-
async function launchSignIn(params) {
|
|
63
|
-
const authorizeUrl = await buildOAuthAuthorizeUrl({
|
|
64
|
-
serverUrl: params.serverUrl,
|
|
65
|
-
callbackUrl: params.callbackUrl,
|
|
66
|
-
oauthClientId: params.oauthClientId,
|
|
67
|
-
scope: params.scope,
|
|
68
|
-
provider: params.provider,
|
|
69
|
-
extraQueryParams: params.extraQueryParams,
|
|
70
|
-
storage: params.storage,
|
|
71
|
-
});
|
|
72
|
-
if (typeof window === "undefined") {
|
|
73
|
-
throw new Error("LoginScope requires a browser environment");
|
|
74
|
-
}
|
|
75
|
-
window.location.assign(authorizeUrl.toString());
|
|
76
|
-
}
|
|
77
|
-
export function useLoginScope(options) {
|
|
78
|
-
const storage = options.storage ?? getDefaultStorage();
|
|
79
|
-
const auth = options.auth ?? meshagentAuth;
|
|
80
|
-
const authSnapshot = useMeshagentAuth(auth);
|
|
81
|
-
const session = useMemo(() => new OAuthSessionManager({
|
|
82
|
-
serverUrl: options.serverUrl,
|
|
83
|
-
clientId: options.oauthClientId,
|
|
84
|
-
auth,
|
|
85
|
-
}), [auth, options.oauthClientId, options.serverUrl]);
|
|
86
|
-
const autoSignIn = options.autoSignIn ?? true;
|
|
87
|
-
const extraQueryParamsKey = useMemo(() => serializeExtraQueryParams(options.extraQueryParams), [options.extraQueryParams]);
|
|
88
|
-
const [signInFailed, setSignInFailed] = useState(null);
|
|
89
|
-
const [isSigningIn, setIsSigningIn] = useState(false);
|
|
90
|
-
const [isCancelled, setIsCancelled] = useState(false);
|
|
91
|
-
const [refreshVersion, setRefreshVersion] = useState(0);
|
|
92
|
-
const signIn = async (provider) => {
|
|
93
|
-
setIsSigningIn(true);
|
|
94
|
-
setSignInFailed(null);
|
|
95
|
-
setIsCancelled(false);
|
|
96
|
-
try {
|
|
97
|
-
await launchSignIn({
|
|
98
|
-
serverUrl: options.serverUrl,
|
|
99
|
-
callbackUrl: options.callbackUrl,
|
|
100
|
-
oauthClientId: options.oauthClientId,
|
|
101
|
-
scope: options.scope,
|
|
102
|
-
provider,
|
|
103
|
-
extraQueryParams: options.extraQueryParams,
|
|
104
|
-
storage,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
setSignInFailed(error);
|
|
109
|
-
setIsSigningIn(false);
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
const loginQuery = useQuery({
|
|
113
|
-
queryKey: [
|
|
114
|
-
"login-scope",
|
|
115
|
-
toUrl(options.serverUrl).toString(),
|
|
116
|
-
toUrl(options.callbackUrl).toString(),
|
|
117
|
-
options.oauthClientId,
|
|
118
|
-
options.scope ?? "profile",
|
|
119
|
-
extraQueryParamsKey,
|
|
120
|
-
autoSignIn,
|
|
121
|
-
authSnapshot.accessToken,
|
|
122
|
-
refreshVersion,
|
|
123
|
-
],
|
|
124
|
-
retry: false,
|
|
125
|
-
refetchOnReconnect: false,
|
|
126
|
-
refetchOnWindowFocus: false,
|
|
127
|
-
queryFn: async ({ signal }) => {
|
|
128
|
-
if (!authSnapshot.accessToken) {
|
|
129
|
-
setSignInFailed(null);
|
|
130
|
-
if (autoSignIn) {
|
|
131
|
-
setIsSigningIn(true);
|
|
132
|
-
try {
|
|
133
|
-
await launchSignIn({
|
|
134
|
-
serverUrl: options.serverUrl,
|
|
135
|
-
callbackUrl: options.callbackUrl,
|
|
136
|
-
oauthClientId: options.oauthClientId,
|
|
137
|
-
scope: options.scope,
|
|
138
|
-
provider: null,
|
|
139
|
-
extraQueryParams: options.extraQueryParams,
|
|
140
|
-
storage,
|
|
141
|
-
});
|
|
142
|
-
return {
|
|
143
|
-
failed: null,
|
|
144
|
-
isLoginLaunched: false,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
setIsSigningIn(false);
|
|
149
|
-
return {
|
|
150
|
-
failed: error,
|
|
151
|
-
isLoginLaunched: true,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
setIsSigningIn(false);
|
|
156
|
-
return {
|
|
157
|
-
failed: null,
|
|
158
|
-
isLoginLaunched: true,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
let accessToken;
|
|
162
|
-
try {
|
|
163
|
-
accessToken = await session.getValidAccessTokenOrThrow();
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
auth.signOut();
|
|
167
|
-
setIsSigningIn(false);
|
|
168
|
-
return {
|
|
169
|
-
failed: error,
|
|
170
|
-
isLoginLaunched: true,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
try {
|
|
174
|
-
const user = await fetchUserProfile({
|
|
175
|
-
serverUrl: options.serverUrl,
|
|
176
|
-
accessToken,
|
|
177
|
-
signal,
|
|
178
|
-
});
|
|
179
|
-
auth.setUser(user);
|
|
180
|
-
setSignInFailed(null);
|
|
181
|
-
setIsSigningIn(false);
|
|
182
|
-
return {
|
|
183
|
-
failed: null,
|
|
184
|
-
isLoginLaunched: false,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
setIsSigningIn(false);
|
|
189
|
-
if (isAuthProfileError(error)) {
|
|
190
|
-
auth.signOut();
|
|
191
|
-
return {
|
|
192
|
-
failed: error,
|
|
193
|
-
isLoginLaunched: true,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
return {
|
|
197
|
-
failed: error,
|
|
198
|
-
isLoginLaunched: false,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
},
|
|
1
|
+
import { useAuth } from "./use-auth";
|
|
2
|
+
export function useLoginScope(props) {
|
|
3
|
+
return useAuth({
|
|
4
|
+
...props,
|
|
5
|
+
scope: props.scope ?? "email",
|
|
202
6
|
});
|
|
203
|
-
const refresh = () => {
|
|
204
|
-
setSignInFailed(null);
|
|
205
|
-
setIsCancelled(false);
|
|
206
|
-
setRefreshVersion((version) => version + 1);
|
|
207
|
-
};
|
|
208
|
-
const failed = signInFailed ?? (loginQuery.isFetching ? null : loginQuery.data?.failed ?? null);
|
|
209
|
-
const isLoginLaunched = signInFailed !== null
|
|
210
|
-
? true
|
|
211
|
-
: loginQuery.data?.isLoginLaunched ?? false;
|
|
212
|
-
const refreshing = loginQuery.isPending || loginQuery.isFetching;
|
|
213
|
-
return {
|
|
214
|
-
failed,
|
|
215
|
-
isCancelled,
|
|
216
|
-
isSigningIn,
|
|
217
|
-
refreshing,
|
|
218
|
-
user: authSnapshot.user,
|
|
219
|
-
signIn,
|
|
220
|
-
refresh,
|
|
221
|
-
isLoginLaunched,
|
|
222
|
-
};
|
|
223
7
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meshagent/meshagent-react-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.2",
|
|
4
4
|
"description": "Meshagent React Auth Helpers",
|
|
5
5
|
"homepage": "https://github.com/meshagent/meshagent-react-auth",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "mkdir -p dist && bash ./scripts/build.sh"
|
|
7
|
+
"build": "mkdir -p dist && bash ./scripts/build.sh",
|
|
8
|
+
"test": "jest",
|
|
9
|
+
"test:watch": "jest --watch"
|
|
8
10
|
},
|
|
9
11
|
"author": "Meshagent Software",
|
|
10
12
|
"license": "Apache-2.0",
|
|
@@ -26,8 +28,8 @@
|
|
|
26
28
|
"CHANGELOG.md"
|
|
27
29
|
],
|
|
28
30
|
"dependencies": {
|
|
29
|
-
"@meshagent/meshagent": "^0.
|
|
30
|
-
"@meshagent/meshagent-ts-auth": "^0.
|
|
31
|
+
"@meshagent/meshagent": "^0.37.2",
|
|
32
|
+
"@meshagent/meshagent-ts-auth": "^0.37.2",
|
|
31
33
|
"@tanstack/react-query": "^5.95.2",
|
|
32
34
|
"@tanstack/react-query-devtools": "^5.95.2",
|
|
33
35
|
"react": "^19.1.8",
|
|
@@ -42,4 +44,4 @@
|
|
|
42
44
|
"overrides": {
|
|
43
45
|
"rollup": "4.52.5"
|
|
44
46
|
}
|
|
45
|
-
}
|
|
47
|
+
}
|