@visin/frontend-core 0.1.4 → 0.1.5
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/apiClient.d.ts +6 -9
- package/dist/apiClient.d.ts.map +1 -1
- package/dist/apiClient.js +7 -9
- package/dist/apiClient.js.map +1 -1
- package/dist/auth/authService.d.ts +5 -4
- package/dist/auth/authService.d.ts.map +1 -1
- package/dist/auth/authService.js +38 -32
- package/dist/auth/authService.js.map +1 -1
- package/package.json +1 -1
package/dist/apiClient.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export interface ApiClientOptions {
|
|
2
2
|
/** Read fresh at call time (app config may not be resolved yet at module load). */
|
|
3
3
|
baseUrl: () => string;
|
|
4
|
-
/** Reads the current auth token, e.g. `() => localStorage.getItem('authToken')`. */
|
|
5
|
-
getToken?: () => string | null;
|
|
6
4
|
/** Called on a 401 response, e.g. to redirect to the login page. */
|
|
7
5
|
onUnauthorized?: () => void;
|
|
8
6
|
}
|
|
@@ -16,14 +14,13 @@ export declare class ApiError extends Error {
|
|
|
16
14
|
constructor(status: number, message: string, body?: unknown);
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
|
-
* Generic authenticated JSON fetch wrapper — base URL handling,
|
|
20
|
-
*
|
|
17
|
+
* Generic authenticated JSON fetch wrapper — base URL handling, structured
|
|
18
|
+
* errors, and an opt-in 401 → redirect-to-auth hook.
|
|
21
19
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* with near-identical logic; new call sites can adopt this instead.
|
|
20
|
+
* Auth rides the shared `access_token` httpOnly cookie (COOKIE_DOMAIN is a
|
|
21
|
+
* shared parent domain across every Visin subdomain), so every request
|
|
22
|
+
* defaults to `credentials: 'include'` — callers can still override via
|
|
23
|
+
* `init.credentials` for the rare request that shouldn't send it.
|
|
27
24
|
*/
|
|
28
25
|
export declare function createApiClient(options: ApiClientOptions): {
|
|
29
26
|
request: <T = unknown>(path: string, init?: ApiRequestOptions) => Promise<T>;
|
package/dist/apiClient.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../src/apiClient.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,
|
|
1
|
+
{"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../src/apiClient.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,oJAAoJ;IACpJ,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;gBAEF,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;CAM5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB;cAChC,CAAC,kBAAkB,MAAM,SAAQ,iBAAiB,KAAQ,OAAO,CAAC,CAAC,CAAC;UAmCnF,CAAC,kBAAkB,MAAM,SAAS,iBAAiB;WAClD,CAAC,kBAAkB,MAAM,SAAS,OAAO,SAAS,iBAAiB;UAEpE,CAAC,kBAAkB,MAAM,SAAS,OAAO,SAAS,iBAAiB;YAEjE,CAAC,kBAAkB,MAAM,SAAS,OAAO,SAAS,iBAAiB;aAElE,CAAC,kBAAkB,MAAM,SAAS,iBAAiB;EAE/D;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC"}
|
package/dist/apiClient.js
CHANGED
|
@@ -7,24 +7,22 @@ export class ApiError extends Error {
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
* Generic authenticated JSON fetch wrapper — base URL handling,
|
|
11
|
-
*
|
|
10
|
+
* Generic authenticated JSON fetch wrapper — base URL handling, structured
|
|
11
|
+
* errors, and an opt-in 401 → redirect-to-auth hook.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* with near-identical logic; new call sites can adopt this instead.
|
|
13
|
+
* Auth rides the shared `access_token` httpOnly cookie (COOKIE_DOMAIN is a
|
|
14
|
+
* shared parent domain across every Visin subdomain), so every request
|
|
15
|
+
* defaults to `credentials: 'include'` — callers can still override via
|
|
16
|
+
* `init.credentials` for the rare request that shouldn't send it.
|
|
18
17
|
*/
|
|
19
18
|
export function createApiClient(options) {
|
|
20
19
|
async function request(path, init = {}) {
|
|
21
20
|
const { skipAuthRedirect, headers, ...rest } = init;
|
|
22
|
-
const token = options.getToken?.();
|
|
23
21
|
const response = await fetch(`${options.baseUrl()}${path}`, {
|
|
22
|
+
credentials: 'include',
|
|
24
23
|
...rest,
|
|
25
24
|
headers: {
|
|
26
25
|
'Content-Type': 'application/json',
|
|
27
|
-
...(token && { Authorization: `Bearer ${token}` }),
|
|
28
26
|
...headers
|
|
29
27
|
}
|
|
30
28
|
});
|
package/dist/apiClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiClient.js","sourceRoot":"","sources":["../src/apiClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apiClient.js","sourceRoot":"","sources":["../src/apiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,16 +26,17 @@ export interface AuthServiceOptions {
|
|
|
26
26
|
authFrontUrl: () => string;
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
* Session-management logic shared by every Visin frontend:
|
|
30
|
-
* `/auth/
|
|
31
|
-
*
|
|
29
|
+
* Session-management logic shared by every Visin frontend: `/auth/verify` +
|
|
30
|
+
* `/auth/profile` checks, logout, and the redirect to auth-front's login
|
|
31
|
+
* page. Auth rides the shared `access_token` httpOnly cookie (see
|
|
32
|
+
* `createApiClient`) rather than a token this service has to store itself.
|
|
33
|
+
* Each app previously hand-rolled this
|
|
32
34
|
* (`account-front/services/authService.ts`, `vision-front/contexts/AuthContext.tsx`)
|
|
33
35
|
* with near-identical but subtly diverging logic; wrap the result in
|
|
34
36
|
* `createAuthContext` for a React Context/hook, or use it directly for a
|
|
35
37
|
* plain-object service.
|
|
36
38
|
*/
|
|
37
39
|
export declare function createAuthService({ authServiceUrl, authFrontUrl }: AuthServiceOptions): {
|
|
38
|
-
getToken: () => string | null;
|
|
39
40
|
checkAuth: () => Promise<AuthCheckResult>;
|
|
40
41
|
getCurrentUser: () => Promise<AuthUser | null>;
|
|
41
42
|
getProfile: () => Promise<AuthUser | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authService.d.ts","sourceRoot":"","sources":["../../src/auth/authService.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,4FAA4F;IAC5F,YAAY,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED
|
|
1
|
+
{"version":3,"file":"authService.d.ts","sourceRoot":"","sources":["../../src/auth/authService.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,4FAA4F;IAC5F,YAAY,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE,kBAAkB;qBAS9D,OAAO,CAAC,eAAe,CAAC;0BA+Bb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;sBAK5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;2BAUnB,OAAO,CAAC,OAAO,CAAC;kBAKzB,OAAO,CAAC,OAAO,CAAC;kCAUJ,MAAM,KAAG,IAAI;EAMnD;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
package/dist/auth/authService.js
CHANGED
|
@@ -1,38 +1,47 @@
|
|
|
1
|
-
import { createApiClient } from '../apiClient';
|
|
1
|
+
import { createApiClient, ApiError } from '../apiClient';
|
|
2
2
|
/**
|
|
3
|
-
* Session-management logic shared by every Visin frontend:
|
|
4
|
-
* `/auth/
|
|
5
|
-
*
|
|
3
|
+
* Session-management logic shared by every Visin frontend: `/auth/verify` +
|
|
4
|
+
* `/auth/profile` checks, logout, and the redirect to auth-front's login
|
|
5
|
+
* page. Auth rides the shared `access_token` httpOnly cookie (see
|
|
6
|
+
* `createApiClient`) rather than a token this service has to store itself.
|
|
7
|
+
* Each app previously hand-rolled this
|
|
6
8
|
* (`account-front/services/authService.ts`, `vision-front/contexts/AuthContext.tsx`)
|
|
7
9
|
* with near-identical but subtly diverging logic; wrap the result in
|
|
8
10
|
* `createAuthContext` for a React Context/hook, or use it directly for a
|
|
9
11
|
* plain-object service.
|
|
10
12
|
*/
|
|
11
13
|
export function createAuthService({ authServiceUrl, authFrontUrl }) {
|
|
12
|
-
const client = createApiClient({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
const client = createApiClient({ baseUrl: authServiceUrl });
|
|
15
|
+
// Shared by concurrent callers (e.g. React StrictMode's double effect-invoke
|
|
16
|
+
// in development, or multiple components independently checking auth on
|
|
17
|
+
// first mount) so they trigger one /auth/verify request, not one each.
|
|
18
|
+
// Cleared once it settles, so the next distinct check gets a fresh request.
|
|
19
|
+
let inFlightCheck = null;
|
|
20
|
+
function checkAuth() {
|
|
21
|
+
if (inFlightCheck) {
|
|
22
|
+
return inFlightCheck;
|
|
23
|
+
}
|
|
24
|
+
inFlightCheck = (async () => {
|
|
25
|
+
try {
|
|
26
|
+
const data = await client.get('/auth/verify', { skipAuthRedirect: true });
|
|
27
|
+
if (data.success) {
|
|
28
|
+
return { authenticated: data.authenticated, user: data.user ?? null };
|
|
25
29
|
}
|
|
26
|
-
return { authenticated:
|
|
30
|
+
return { authenticated: false, user: null };
|
|
27
31
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
catch (error) {
|
|
33
|
+
// A 401 here just means "not logged in" — the normal state for an
|
|
34
|
+
// anonymous visitor, not a bug worth an error-level log.
|
|
35
|
+
if (!(error instanceof ApiError && error.status === 401)) {
|
|
36
|
+
console.error('Auth check failed:', error);
|
|
37
|
+
}
|
|
38
|
+
return { authenticated: false, user: null };
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
inFlightCheck = null;
|
|
42
|
+
}
|
|
43
|
+
})();
|
|
44
|
+
return inFlightCheck;
|
|
36
45
|
}
|
|
37
46
|
async function getCurrentUser() {
|
|
38
47
|
const result = await checkAuth();
|
|
@@ -40,7 +49,7 @@ export function createAuthService({ authServiceUrl, authFrontUrl }) {
|
|
|
40
49
|
}
|
|
41
50
|
async function getProfile() {
|
|
42
51
|
try {
|
|
43
|
-
const data = await client.get('/auth/profile'
|
|
52
|
+
const data = await client.get('/auth/profile');
|
|
44
53
|
return data.success ? (data.user ?? null) : null;
|
|
45
54
|
}
|
|
46
55
|
catch (error) {
|
|
@@ -54,10 +63,7 @@ export function createAuthService({ authServiceUrl, authFrontUrl }) {
|
|
|
54
63
|
}
|
|
55
64
|
async function logout() {
|
|
56
65
|
try {
|
|
57
|
-
const data = await client.post('/auth/logout'
|
|
58
|
-
if (data.success) {
|
|
59
|
-
localStorage.removeItem('authToken');
|
|
60
|
-
}
|
|
66
|
+
const data = await client.post('/auth/logout');
|
|
61
67
|
return data.success;
|
|
62
68
|
}
|
|
63
69
|
catch (error) {
|
|
@@ -69,6 +75,6 @@ export function createAuthService({ authServiceUrl, authFrontUrl }) {
|
|
|
69
75
|
const currentUrl = returnUrl || window.location.href;
|
|
70
76
|
window.location.href = `${authFrontUrl()}?redirect_uri=${encodeURIComponent(currentUrl)}`;
|
|
71
77
|
}
|
|
72
|
-
return {
|
|
78
|
+
return { checkAuth, getCurrentUser, getProfile, isAuthenticated, logout, redirectToLogin };
|
|
73
79
|
}
|
|
74
80
|
//# sourceMappingURL=authService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authService.js","sourceRoot":"","sources":["../../src/auth/authService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"authService.js","sourceRoot":"","sources":["../../src/auth/authService.ts"],"names":[],"mappings":"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"}
|