@nhost/nhost-js 3.2.8 → 5.0.0-beta.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/README.md +73 -37
- package/dist/nhost-js/auth.cjs.js +2 -0
- package/dist/nhost-js/auth.cjs.js.map +1 -0
- package/dist/nhost-js/auth.es.js +589 -0
- package/dist/nhost-js/auth.es.js.map +1 -0
- package/dist/nhost-js/fetch.cjs.js +2 -0
- package/dist/nhost-js/fetch.cjs.js.map +1 -0
- package/dist/nhost-js/fetch.es.js +10 -0
- package/dist/nhost-js/fetch.es.js.map +1 -0
- package/dist/nhost-js/functions.cjs.js +2 -0
- package/dist/nhost-js/functions.cjs.js.map +1 -0
- package/dist/nhost-js/functions.es.js +31 -0
- package/dist/nhost-js/functions.es.js.map +1 -0
- package/dist/nhost-js/graphql.cjs.js +2 -0
- package/dist/nhost-js/graphql.cjs.js.map +1 -0
- package/dist/nhost-js/graphql.es.js +35 -0
- package/dist/nhost-js/graphql.es.js.map +1 -0
- package/dist/nhost-js/storage.cjs.js +2 -0
- package/dist/nhost-js/storage.cjs.js.map +1 -0
- package/dist/nhost-js/storage.es.js +205 -0
- package/dist/nhost-js/storage.es.js.map +1 -0
- package/dist/nhost-js.cjs.js +2 -0
- package/dist/nhost-js.cjs.js.map +1 -0
- package/dist/nhost-js.es.js +497 -0
- package/dist/nhost-js.es.js.map +1 -0
- package/dist/nhost-js.umd.js +2 -0
- package/dist/nhost-js.umd.js.map +1 -0
- package/dist/src/auth/client.d.ts +430 -0
- package/dist/src/auth/client.d.ts.map +1 -0
- package/dist/src/auth/client.js +727 -0
- package/dist/src/auth/client.js.map +1 -0
- package/dist/src/auth/index.d.ts +11 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/index.js +11 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/interface.d.ts +142 -0
- package/dist/src/auth/interface.d.ts.map +1 -0
- package/dist/src/auth/interface.js +2 -0
- package/dist/src/auth/interface.js.map +1 -0
- package/dist/src/fetch/index.d.ts +53 -0
- package/dist/src/fetch/index.d.ts.map +1 -0
- package/dist/src/fetch/index.js +40 -0
- package/dist/src/fetch/index.js.map +1 -0
- package/dist/src/functions/client.d.ts +47 -0
- package/dist/src/functions/client.d.ts.map +1 -0
- package/dist/src/functions/client.js +62 -0
- package/dist/src/functions/client.js.map +1 -0
- package/dist/src/functions/index.d.ts +10 -0
- package/dist/src/functions/index.d.ts.map +1 -0
- package/dist/src/functions/index.js +10 -0
- package/dist/src/functions/index.js.map +1 -0
- package/dist/src/graphql/client.d.ts +89 -0
- package/dist/src/graphql/client.d.ts.map +1 -0
- package/dist/src/graphql/client.js +49 -0
- package/dist/src/graphql/client.js.map +1 -0
- package/dist/src/graphql/index.d.ts +10 -0
- package/dist/src/graphql/index.d.ts.map +1 -0
- package/dist/src/graphql/index.js +10 -0
- package/dist/src/graphql/index.js.map +1 -0
- package/dist/src/index.d.ts +184 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +251 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/middlewareAttachToken.d.ts +24 -0
- package/dist/src/middlewareAttachToken.d.ts.map +1 -0
- package/dist/src/middlewareAttachToken.js +60 -0
- package/dist/src/middlewareAttachToken.js.map +1 -0
- package/dist/src/middlewareRefreshSession.d.ts +43 -0
- package/dist/src/middlewareRefreshSession.d.ts.map +1 -0
- package/dist/src/middlewareRefreshSession.js +190 -0
- package/dist/src/middlewareRefreshSession.js.map +1 -0
- package/dist/src/middlewareResponseSession.d.ts +26 -0
- package/dist/src/middlewareResponseSession.d.ts.map +1 -0
- package/dist/src/middlewareResponseSession.js +83 -0
- package/dist/src/middlewareResponseSession.js.map +1 -0
- package/dist/src/sessionStorage.d.ts +123 -0
- package/dist/src/sessionStorage.d.ts.map +1 -0
- package/dist/src/sessionStorage.js +165 -0
- package/dist/src/sessionStorage.js.map +1 -0
- package/dist/src/storage/client.d.ts +184 -0
- package/dist/src/storage/client.d.ts.map +1 -0
- package/dist/src/storage/client.js +249 -0
- package/dist/src/storage/client.js.map +1 -0
- package/dist/src/storage/index.d.ts +11 -0
- package/dist/src/storage/index.d.ts.map +1 -0
- package/dist/src/storage/index.js +11 -0
- package/dist/src/storage/index.js.map +1 -0
- package/dist/src/storage/interface.d.ts +52 -0
- package/dist/src/storage/interface.d.ts.map +1 -0
- package/dist/src/storage/interface.js +2 -0
- package/dist/src/storage/interface.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +109 -63
- package/LICENSE +0 -21
- package/dist/clients/auth.d.ts +0 -8
- package/dist/clients/auth.d.ts.map +0 -1
- package/dist/clients/functions/index.d.ts +0 -107
- package/dist/clients/functions/index.d.ts.map +0 -1
- package/dist/clients/functions/types.d.ts +0 -28
- package/dist/clients/functions/types.d.ts.map +0 -1
- package/dist/clients/graphql.d.ts +0 -8
- package/dist/clients/graphql.d.ts.map +0 -1
- package/dist/clients/index.d.ts +0 -6
- package/dist/clients/index.d.ts.map +0 -1
- package/dist/clients/nhost.d.ts +0 -83
- package/dist/clients/nhost.d.ts.map +0 -1
- package/dist/clients/storage.d.ts +0 -8
- package/dist/clients/storage.d.ts.map +0 -1
- package/dist/index.cjs.js +0 -2
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.d.ts.map +0 -1
- package/dist/index.esm.js +0 -344
- package/dist/index.esm.js.map +0 -1
- package/dist/utils/helpers.d.ts +0 -20
- package/dist/utils/helpers.d.ts.map +0 -1
- package/dist/utils/types.d.ts +0 -57
- package/dist/utils/types.d.ts.map +0 -1
- package/umd/nhost-js.umd.js +0 -22
- package/umd/nhost-js.umd.js.map +0 -1
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Auth token refresh middleware for the Nhost SDK.
|
|
3
|
+
*
|
|
4
|
+
* This module provides middleware functionality to automatically refresh
|
|
5
|
+
* authentication tokens before they expire, ensuring seamless API access
|
|
6
|
+
* without requiring manual token refresh by the application.
|
|
7
|
+
*/
|
|
8
|
+
import {} from "./sessionStorage";
|
|
9
|
+
import {} from "./fetch";
|
|
10
|
+
/**
|
|
11
|
+
* Extracts the expiration time from a JWT token
|
|
12
|
+
* @param token - JWT token string
|
|
13
|
+
* @returns Expiration timestamp in milliseconds, or 0 if unable to extract
|
|
14
|
+
*/
|
|
15
|
+
export const extractTokenExpiration = (token) => {
|
|
16
|
+
try {
|
|
17
|
+
// JWT tokens are in the format header.payload.signature
|
|
18
|
+
const parts = token.split(".");
|
|
19
|
+
if (parts.length !== 3) {
|
|
20
|
+
console.warn("Token does not have three parts");
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
// At this point, we know parts has exactly 3 elements
|
|
24
|
+
// Use a non-null assertion or check explicitly
|
|
25
|
+
const payloadPart = parts[1];
|
|
26
|
+
if (!payloadPart) {
|
|
27
|
+
console.warn("Payload part is empty");
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
// Decode the payload (middle part)
|
|
31
|
+
const base64 = payloadPart.replace(/-/g, "+").replace(/_/g, "/");
|
|
32
|
+
const payload = decodeTokenPayload(base64);
|
|
33
|
+
if (payload.exp) {
|
|
34
|
+
// exp claim is in seconds, convert to milliseconds
|
|
35
|
+
return payload.exp * 1000;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.warn("No exp claim found in token");
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.warn("Failed to extract token expiration:", error);
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Decodes a base64-encoded JWT payload
|
|
49
|
+
* @param base64Payload - Base64-encoded payload
|
|
50
|
+
* @returns Decoded payload as an object
|
|
51
|
+
*/
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
+
function decodeTokenPayload(base64Payload) {
|
|
54
|
+
try {
|
|
55
|
+
let jsonPayload;
|
|
56
|
+
if (typeof window !== "undefined") {
|
|
57
|
+
// Browser environment
|
|
58
|
+
jsonPayload = decodeURIComponent(window
|
|
59
|
+
.atob(base64Payload)
|
|
60
|
+
.split("")
|
|
61
|
+
.map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2))
|
|
62
|
+
.join(""));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Node.js environment
|
|
66
|
+
const buffer = Buffer.from(base64Payload, "base64");
|
|
67
|
+
jsonPayload = buffer.toString("utf8");
|
|
68
|
+
}
|
|
69
|
+
return JSON.parse(jsonPayload);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
console.warn("Error decoding token payload:", e);
|
|
73
|
+
throw e;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Creates a fetch middleware that automatically refreshes authentication tokens.
|
|
78
|
+
*
|
|
79
|
+
* This middleware:
|
|
80
|
+
* 1. Checks if the current token is about to expire
|
|
81
|
+
* 2. If so, uses the refresh token to obtain a new access token
|
|
82
|
+
*
|
|
83
|
+
* The middleware handles token refresh transparently, so the application
|
|
84
|
+
* doesn't need to manually refresh tokens.
|
|
85
|
+
*
|
|
86
|
+
* @param authClient - Auth API client for token refresh operations
|
|
87
|
+
* @param storage - Storage implementation for persisting session data
|
|
88
|
+
* @param options - Configuration options for token refresh behavior
|
|
89
|
+
* @returns A middleware function that can be used in the fetch chain
|
|
90
|
+
*/
|
|
91
|
+
export const createSessionRefreshMiddleware = (authClient, storage, options) => {
|
|
92
|
+
const { marginSeconds = 60 } = options || {};
|
|
93
|
+
// Session state
|
|
94
|
+
let currentSession = null;
|
|
95
|
+
let tokenExpiresAt = 0;
|
|
96
|
+
// Create and return the chain function
|
|
97
|
+
return (next) => {
|
|
98
|
+
return async (url, options = {}) => {
|
|
99
|
+
// Skip token handling for certain requests
|
|
100
|
+
if (shouldSkipTokenHandling(url, options, authClient.baseURL)) {
|
|
101
|
+
return next(url, options);
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
// Get current session from storage
|
|
105
|
+
currentSession = storage.get();
|
|
106
|
+
if (currentSession?.accessToken) {
|
|
107
|
+
tokenExpiresAt = extractTokenExpiration(currentSession.accessToken);
|
|
108
|
+
}
|
|
109
|
+
// If we don't have a session, proceed without authorization
|
|
110
|
+
if (!currentSession) {
|
|
111
|
+
return next(url, options);
|
|
112
|
+
}
|
|
113
|
+
// Check if token needs refresh
|
|
114
|
+
if (isTokenExpiringSoon(tokenExpiresAt, marginSeconds)) {
|
|
115
|
+
if (currentSession.refreshToken) {
|
|
116
|
+
// Refresh the token
|
|
117
|
+
const refreshedSession = await refreshToken(authClient, storage, currentSession.refreshToken);
|
|
118
|
+
if (refreshedSession) {
|
|
119
|
+
currentSession = refreshedSession;
|
|
120
|
+
tokenExpiresAt = extractTokenExpiration(refreshedSession.accessToken);
|
|
121
|
+
storage.set(refreshedSession);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Continue with the fetch chain
|
|
126
|
+
return next(url, options);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
console.error("Error in token refresh chain:", error);
|
|
130
|
+
// Continue with the request even if token refresh fails
|
|
131
|
+
return next(url, options);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Performs the actual token refresh operation using the auth client
|
|
138
|
+
*
|
|
139
|
+
* @param authClient - Auth API client to use for token refresh
|
|
140
|
+
* @param storage - Storage implementation for persisting the new session
|
|
141
|
+
* @param refreshToken - Current refresh token to use
|
|
142
|
+
* @returns A new session if refresh was successful, null otherwise
|
|
143
|
+
*/
|
|
144
|
+
async function refreshToken(authClient, storage, refreshToken) {
|
|
145
|
+
try {
|
|
146
|
+
const refreshResponse = await authClient.refreshToken({ refreshToken });
|
|
147
|
+
if (refreshResponse.status === 200) {
|
|
148
|
+
const session = refreshResponse.body;
|
|
149
|
+
storage.set(session);
|
|
150
|
+
return session;
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error("Error refreshing token:", error);
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Determines if token handling should be skipped for this request
|
|
161
|
+
*
|
|
162
|
+
* @param url - Request URL
|
|
163
|
+
* @param options - Request options
|
|
164
|
+
* @param authApiUrl - Base URL for auth API
|
|
165
|
+
* @returns True if token handling should be skipped, false otherwise
|
|
166
|
+
*/
|
|
167
|
+
function shouldSkipTokenHandling(url, options, authApiUrl) {
|
|
168
|
+
const headers = new Headers(options.headers || {});
|
|
169
|
+
// If Authorization header is explicitly set, skip token handling
|
|
170
|
+
if (headers.has("Authorization")) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
// If calling the token endpoint, skip to avoid infinite loops
|
|
174
|
+
if (url === `${authApiUrl}/token`) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Checks if a token is expiring soon and needs to be refreshed
|
|
181
|
+
*
|
|
182
|
+
* @param expiresAt - Token expiration timestamp in milliseconds
|
|
183
|
+
* @param marginSeconds - Number of seconds before expiration to trigger refresh
|
|
184
|
+
* @returns True if token is expiring soon, false otherwise
|
|
185
|
+
*/
|
|
186
|
+
function isTokenExpiringSoon(expiresAt, marginSeconds) {
|
|
187
|
+
const currentTime = Date.now();
|
|
188
|
+
return expiresAt - currentTime < marginSeconds * 1000;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=middlewareRefreshSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middlewareRefreshSession.js","sourceRoot":"","sources":["../../src/middlewareRefreshSession.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Session response middleware for the Nhost SDK.
|
|
3
|
+
*
|
|
4
|
+
* This module provides middleware functionality to automatically extract
|
|
5
|
+
* and persist session information from authentication responses, ensuring
|
|
6
|
+
* that new sessions are properly stored after sign-in operations.
|
|
7
|
+
*/
|
|
8
|
+
import { type SessionStorageInterface } from "./sessionStorage";
|
|
9
|
+
import { type ChainFunction } from "./fetch";
|
|
10
|
+
/**
|
|
11
|
+
* Creates a fetch middleware that automatically extracts and stores session data from API responses.
|
|
12
|
+
*
|
|
13
|
+
* This middleware:
|
|
14
|
+
* 1. Monitors responses from authentication-related endpoints
|
|
15
|
+
* 2. Extracts session information when present
|
|
16
|
+
* 3. Stores the session in the provided storage implementation
|
|
17
|
+
* 4. Handles session removal on sign-out
|
|
18
|
+
*
|
|
19
|
+
* This ensures that session data is always up-to-date in storage after operations
|
|
20
|
+
* that create or invalidate sessions.
|
|
21
|
+
*
|
|
22
|
+
* @param storage - Storage implementation for persisting session data
|
|
23
|
+
* @returns A middleware function that can be used in the fetch chain
|
|
24
|
+
*/
|
|
25
|
+
export declare const createSessionResponseMiddleware: (storage: SessionStorageInterface) => ChainFunction;
|
|
26
|
+
//# sourceMappingURL=middlewareResponseSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middlewareResponseSession.d.ts","sourceRoot":"","sources":["../../src/middlewareResponseSession.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,+BAA+B,GAC1C,SAAS,uBAAuB,KAC/B,aAiEF,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Session response middleware for the Nhost SDK.
|
|
3
|
+
*
|
|
4
|
+
* This module provides middleware functionality to automatically extract
|
|
5
|
+
* and persist session information from authentication responses, ensuring
|
|
6
|
+
* that new sessions are properly stored after sign-in operations.
|
|
7
|
+
*/
|
|
8
|
+
import {} from "./auth";
|
|
9
|
+
import {} from "./sessionStorage";
|
|
10
|
+
import {} from "./fetch";
|
|
11
|
+
/**
|
|
12
|
+
* Creates a fetch middleware that automatically extracts and stores session data from API responses.
|
|
13
|
+
*
|
|
14
|
+
* This middleware:
|
|
15
|
+
* 1. Monitors responses from authentication-related endpoints
|
|
16
|
+
* 2. Extracts session information when present
|
|
17
|
+
* 3. Stores the session in the provided storage implementation
|
|
18
|
+
* 4. Handles session removal on sign-out
|
|
19
|
+
*
|
|
20
|
+
* This ensures that session data is always up-to-date in storage after operations
|
|
21
|
+
* that create or invalidate sessions.
|
|
22
|
+
*
|
|
23
|
+
* @param storage - Storage implementation for persisting session data
|
|
24
|
+
* @returns A middleware function that can be used in the fetch chain
|
|
25
|
+
*/
|
|
26
|
+
export const createSessionResponseMiddleware = (storage) => {
|
|
27
|
+
/**
|
|
28
|
+
* Helper function to extract session data from various response formats
|
|
29
|
+
*
|
|
30
|
+
* @param data - Response data to extract session from
|
|
31
|
+
* @returns Session object if found, null otherwise
|
|
32
|
+
*/
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
const sessionExtractor = function (body) {
|
|
35
|
+
// Look for session in common response patterns
|
|
36
|
+
const session =
|
|
37
|
+
// Pattern: { session: {...} }
|
|
38
|
+
body?.session ||
|
|
39
|
+
// Pattern: { data: { session: {...} } }
|
|
40
|
+
body?.data?.session ||
|
|
41
|
+
// Pattern: { accessToken, refreshToken, ... } where data itself is the session
|
|
42
|
+
(body?.accessToken && body?.refreshToken && body) ||
|
|
43
|
+
null;
|
|
44
|
+
return session;
|
|
45
|
+
};
|
|
46
|
+
return (next) => {
|
|
47
|
+
return async (url, options) => {
|
|
48
|
+
// Call the next middleware in the chain
|
|
49
|
+
const response = await next(url, options);
|
|
50
|
+
try {
|
|
51
|
+
// Check if this is a logout request
|
|
52
|
+
if (url.endsWith("/signout")) {
|
|
53
|
+
// Remove session on sign-out
|
|
54
|
+
storage.remove();
|
|
55
|
+
return response;
|
|
56
|
+
}
|
|
57
|
+
// Check if this is an auth-related endpoint that might return session data
|
|
58
|
+
if (url.endsWith("/token") ||
|
|
59
|
+
url.includes("/signin/") ||
|
|
60
|
+
url.includes("/signup/")) {
|
|
61
|
+
// Clone the response to avoid consuming it
|
|
62
|
+
const clonedResponse = response.clone();
|
|
63
|
+
// Parse the JSON data
|
|
64
|
+
const body = await clonedResponse.json().catch(() => null);
|
|
65
|
+
if (body) {
|
|
66
|
+
// Extract session data from response using provided extractor
|
|
67
|
+
const session = sessionExtractor(body);
|
|
68
|
+
// If session data is found, store it
|
|
69
|
+
if (session && session.accessToken && session.refreshToken) {
|
|
70
|
+
storage.set(session);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.warn("Error in session response middleware:", error);
|
|
77
|
+
}
|
|
78
|
+
// Return the original response
|
|
79
|
+
return response;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=middlewareResponseSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middlewareResponseSession.js","sourceRoot":"","sources":["../../src/middlewareResponseSession.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgB,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAgC,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAsB,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAC7C,OAAgC,EACjB,EAAE;IACjB;;;;;OAKG;IACH,8DAA8D;IAC9D,MAAM,gBAAgB,GAAG,UAAU,IAAS;QAC1C,+CAA+C;QAC/C,MAAM,OAAO;QACX,8BAA8B;QAC7B,IAAI,EAAE,OAAmB;YAC1B,wCAAwC;YACvC,IAAI,EAAE,IAAI,EAAE,OAAmB;YAChC,+EAA+E;YAC/E,CAAC,IAAI,EAAE,WAAW,IAAI,IAAI,EAAE,YAAY,IAAK,IAAgB,CAAC;YAC9D,IAAI,CAAC;QAEP,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF,OAAO,CAAC,IAA+D,EAAE,EAAE;QACzE,OAAO,KAAK,EAAE,GAAW,EAAE,OAAqB,EAAE,EAAE;YAClD,wCAAwC;YACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAE1C,IAAI,CAAC;gBACH,oCAAoC;gBACpC,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC7B,6BAA6B;oBAC7B,OAAO,CAAC,MAAM,EAAE,CAAC;oBACjB,OAAO,QAAQ,CAAC;gBAClB,CAAC;gBAED,2EAA2E;gBAC3E,IACE,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;oBACtB,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;oBACxB,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EACxB,CAAC;oBACD,2CAA2C;oBAC3C,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;oBAExC,sBAAsB;oBACtB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;oBAE3D,IAAI,IAAI,EAAE,CAAC;wBACT,8DAA8D;wBAC9D,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;wBAEvC,qCAAqC;wBACrC,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;4BAC3D,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBACvB,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;YAC/D,CAAC;YAED,+BAA+B;YAC/B,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Storage implementations for session persistence in different environments.
|
|
3
|
+
*
|
|
4
|
+
* This module provides different storage adapters for persisting authentication sessions
|
|
5
|
+
* across page reloads and browser sessions.
|
|
6
|
+
*/
|
|
7
|
+
import { type Session } from "./auth";
|
|
8
|
+
/**
|
|
9
|
+
* Session storage interface for session persistence.
|
|
10
|
+
* This interface can be implemented to provide custom storage solutions.
|
|
11
|
+
*/
|
|
12
|
+
export interface SessionStorageInterface {
|
|
13
|
+
/**
|
|
14
|
+
* Get the current session from storage
|
|
15
|
+
* @returns The stored session or null if not found
|
|
16
|
+
*/
|
|
17
|
+
get(): Session | null;
|
|
18
|
+
/**
|
|
19
|
+
* Set the session in storage
|
|
20
|
+
* @param value - The session to store
|
|
21
|
+
*/
|
|
22
|
+
set(value: Session): void;
|
|
23
|
+
/**
|
|
24
|
+
* Remove the session from storage
|
|
25
|
+
*/
|
|
26
|
+
remove(): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Default storage key used for storing the Nhost session
|
|
30
|
+
*/
|
|
31
|
+
export declare const DEFAULT_SESSION_KEY = "nhostSession";
|
|
32
|
+
/**
|
|
33
|
+
* Browser localStorage implementation of StorageInterface.
|
|
34
|
+
* Persists the session across page reloads and browser restarts.
|
|
35
|
+
*/
|
|
36
|
+
export declare class LocalStorage implements SessionStorageInterface {
|
|
37
|
+
private readonly storageKey;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a new LocalStorage instance
|
|
40
|
+
* @param storageKey - The key to use in localStorage (defaults to "nhostSession")
|
|
41
|
+
*/
|
|
42
|
+
constructor(storageKey?: string);
|
|
43
|
+
/**
|
|
44
|
+
* Gets the session from localStorage
|
|
45
|
+
* @returns The stored session or null if not found
|
|
46
|
+
*/
|
|
47
|
+
get(): Session | null;
|
|
48
|
+
/**
|
|
49
|
+
* Sets the session in localStorage
|
|
50
|
+
* @param value - The session to store
|
|
51
|
+
*/
|
|
52
|
+
set(value: Session): void;
|
|
53
|
+
/**
|
|
54
|
+
* Removes the session from localStorage
|
|
55
|
+
*/
|
|
56
|
+
remove(): void;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* In-memory storage implementation for non-browser environments or when
|
|
60
|
+
* persistent storage is not available or desirable.
|
|
61
|
+
*/
|
|
62
|
+
export declare class MemoryStorage implements SessionStorageInterface {
|
|
63
|
+
private session;
|
|
64
|
+
/**
|
|
65
|
+
* Gets the session from memory
|
|
66
|
+
* @returns The stored session or null if not set
|
|
67
|
+
*/
|
|
68
|
+
get(): Session | null;
|
|
69
|
+
/**
|
|
70
|
+
* Sets the session in memory
|
|
71
|
+
* @param value - The session to store
|
|
72
|
+
*/
|
|
73
|
+
set(value: Session): void;
|
|
74
|
+
/**
|
|
75
|
+
* Clears the session from memory
|
|
76
|
+
*/
|
|
77
|
+
remove(): void;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Cookie-based storage implementation.
|
|
81
|
+
* This storage uses web browser cookies to store the session so it's not
|
|
82
|
+
* available in server-side environments. It is useful though for sinchronizing
|
|
83
|
+
* sessions between client and server environments.
|
|
84
|
+
*/
|
|
85
|
+
export declare class CookieStorage implements SessionStorageInterface {
|
|
86
|
+
private readonly cookieName;
|
|
87
|
+
private readonly expirationDays;
|
|
88
|
+
private readonly secure;
|
|
89
|
+
private readonly sameSite;
|
|
90
|
+
/**
|
|
91
|
+
* Creates a new CookieStorage instance
|
|
92
|
+
* @param cookieName - Name of the cookie to use (defaults to "nhostSession")
|
|
93
|
+
* @param expirationDays - Number of days until the cookie expires (defaults to 30)
|
|
94
|
+
* @param secure - Whether to set the Secure flag on the cookie (defaults to true)
|
|
95
|
+
* @param sameSite - SameSite policy for the cookie (defaults to "lax")
|
|
96
|
+
*/
|
|
97
|
+
constructor(cookieName?: string, expirationDays?: number, secure?: boolean, sameSite?: "strict" | "lax" | "none");
|
|
98
|
+
/**
|
|
99
|
+
* Gets the session from cookies
|
|
100
|
+
* @returns The stored session or null if not found
|
|
101
|
+
*/
|
|
102
|
+
get(): Session | null;
|
|
103
|
+
/**
|
|
104
|
+
* Sets the session in a cookie
|
|
105
|
+
* @param value - The session to store
|
|
106
|
+
*/
|
|
107
|
+
set(value: Session): void;
|
|
108
|
+
/**
|
|
109
|
+
* Removes the session cookie
|
|
110
|
+
*/
|
|
111
|
+
remove(): void;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Detects the best available storage implementation for the current environment.
|
|
115
|
+
*
|
|
116
|
+
* The detection process follows this order:
|
|
117
|
+
* 1. Try to use localStorage if we're in a browser environment
|
|
118
|
+
* 2. Fall back to in-memory storage if localStorage isn't available
|
|
119
|
+
*
|
|
120
|
+
* @returns The best available storage implementation for the current environment
|
|
121
|
+
*/
|
|
122
|
+
export declare const detectStorage: () => SessionStorageInterface;
|
|
123
|
+
//# sourceMappingURL=sessionStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionStorage.d.ts","sourceRoot":"","sources":["../../src/sessionStorage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,GAAG,IAAI,OAAO,GAAG,IAAI,CAAC;IAEtB;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAE1B;;OAEG;IACH,MAAM,IAAI,IAAI,CAAC;CAChB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD;;;GAGG;AACH,qBAAa,YAAa,YAAW,uBAAuB;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC;;;OAGG;gBACS,UAAU,SAAsB;IAI5C;;;OAGG;IACH,GAAG,IAAI,OAAO,GAAG,IAAI;IAUrB;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAIzB;;OAEG;IACH,MAAM,IAAI,IAAI;CAGf;AAED;;;GAGG;AACH,qBAAa,aAAc,YAAW,uBAAuB;IAC3D,OAAO,CAAC,OAAO,CAAwB;IAEvC;;;OAGG;IACH,GAAG,IAAI,OAAO,GAAG,IAAI;IAIrB;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAIzB;;OAEG;IACH,MAAM,IAAI,IAAI;CAGf;AAED;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,uBAAuB;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IAErD;;;;;;OAMG;gBAED,UAAU,SAAsB,EAChC,cAAc,SAAK,EACnB,MAAM,UAAO,EACb,QAAQ,GAAE,QAAQ,GAAG,KAAK,GAAG,MAAc;IAQ7C;;;OAGG;IACH,GAAG,IAAI,OAAO,GAAG,IAAI;IAgBrB;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAYzB;;OAEG;IACH,MAAM,IAAI,IAAI;CAGf;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,QAAO,uBAchC,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Storage implementations for session persistence in different environments.
|
|
3
|
+
*
|
|
4
|
+
* This module provides different storage adapters for persisting authentication sessions
|
|
5
|
+
* across page reloads and browser sessions.
|
|
6
|
+
*/
|
|
7
|
+
import {} from "./auth";
|
|
8
|
+
/**
|
|
9
|
+
* Default storage key used for storing the Nhost session
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_SESSION_KEY = "nhostSession";
|
|
12
|
+
/**
|
|
13
|
+
* Browser localStorage implementation of StorageInterface.
|
|
14
|
+
* Persists the session across page reloads and browser restarts.
|
|
15
|
+
*/
|
|
16
|
+
export class LocalStorage {
|
|
17
|
+
storageKey;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new LocalStorage instance
|
|
20
|
+
* @param storageKey - The key to use in localStorage (defaults to "nhostSession")
|
|
21
|
+
*/
|
|
22
|
+
constructor(storageKey = DEFAULT_SESSION_KEY) {
|
|
23
|
+
this.storageKey = storageKey;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Gets the session from localStorage
|
|
27
|
+
* @returns The stored session or null if not found
|
|
28
|
+
*/
|
|
29
|
+
get() {
|
|
30
|
+
try {
|
|
31
|
+
const value = window.localStorage.getItem(this.storageKey);
|
|
32
|
+
return value ? JSON.parse(value) : null;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
this.remove();
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sets the session in localStorage
|
|
41
|
+
* @param value - The session to store
|
|
42
|
+
*/
|
|
43
|
+
set(value) {
|
|
44
|
+
window.localStorage.setItem(this.storageKey, JSON.stringify(value));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Removes the session from localStorage
|
|
48
|
+
*/
|
|
49
|
+
remove() {
|
|
50
|
+
window.localStorage.removeItem(this.storageKey);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* In-memory storage implementation for non-browser environments or when
|
|
55
|
+
* persistent storage is not available or desirable.
|
|
56
|
+
*/
|
|
57
|
+
export class MemoryStorage {
|
|
58
|
+
session = null;
|
|
59
|
+
/**
|
|
60
|
+
* Gets the session from memory
|
|
61
|
+
* @returns The stored session or null if not set
|
|
62
|
+
*/
|
|
63
|
+
get() {
|
|
64
|
+
return this.session;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sets the session in memory
|
|
68
|
+
* @param value - The session to store
|
|
69
|
+
*/
|
|
70
|
+
set(value) {
|
|
71
|
+
this.session = value;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Clears the session from memory
|
|
75
|
+
*/
|
|
76
|
+
remove() {
|
|
77
|
+
this.session = null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Cookie-based storage implementation.
|
|
82
|
+
* This storage uses web browser cookies to store the session so it's not
|
|
83
|
+
* available in server-side environments. It is useful though for sinchronizing
|
|
84
|
+
* sessions between client and server environments.
|
|
85
|
+
*/
|
|
86
|
+
export class CookieStorage {
|
|
87
|
+
cookieName;
|
|
88
|
+
expirationDays;
|
|
89
|
+
secure;
|
|
90
|
+
sameSite;
|
|
91
|
+
/**
|
|
92
|
+
* Creates a new CookieStorage instance
|
|
93
|
+
* @param cookieName - Name of the cookie to use (defaults to "nhostSession")
|
|
94
|
+
* @param expirationDays - Number of days until the cookie expires (defaults to 30)
|
|
95
|
+
* @param secure - Whether to set the Secure flag on the cookie (defaults to true)
|
|
96
|
+
* @param sameSite - SameSite policy for the cookie (defaults to "lax")
|
|
97
|
+
*/
|
|
98
|
+
constructor(cookieName = DEFAULT_SESSION_KEY, expirationDays = 30, secure = true, sameSite = "lax") {
|
|
99
|
+
this.cookieName = cookieName;
|
|
100
|
+
this.expirationDays = expirationDays;
|
|
101
|
+
this.secure = secure;
|
|
102
|
+
this.sameSite = sameSite;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Gets the session from cookies
|
|
106
|
+
* @returns The stored session or null if not found
|
|
107
|
+
*/
|
|
108
|
+
get() {
|
|
109
|
+
const cookies = document.cookie.split(";");
|
|
110
|
+
for (const cookie of cookies) {
|
|
111
|
+
const [name, value] = cookie.trim().split("=");
|
|
112
|
+
if (name === this.cookieName) {
|
|
113
|
+
try {
|
|
114
|
+
return JSON.parse(decodeURIComponent(value || ""));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
this.remove();
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Sets the session in a cookie
|
|
126
|
+
* @param value - The session to store
|
|
127
|
+
*/
|
|
128
|
+
set(value) {
|
|
129
|
+
const expires = new Date();
|
|
130
|
+
expires.setTime(expires.getTime() + this.expirationDays * 24 * 60 * 60 * 1000);
|
|
131
|
+
const cookieValue = encodeURIComponent(JSON.stringify(value));
|
|
132
|
+
const cookieString = `${this.cookieName}=${cookieValue}; expires=${expires.toUTCString()}; path=/; ${this.secure ? "secure; " : ""}SameSite=${this.sameSite}`;
|
|
133
|
+
document.cookie = cookieString;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Removes the session cookie
|
|
137
|
+
*/
|
|
138
|
+
remove() {
|
|
139
|
+
document.cookie = `${this.cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; ${this.secure ? "secure; " : ""}SameSite=${this.sameSite}`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Detects the best available storage implementation for the current environment.
|
|
144
|
+
*
|
|
145
|
+
* The detection process follows this order:
|
|
146
|
+
* 1. Try to use localStorage if we're in a browser environment
|
|
147
|
+
* 2. Fall back to in-memory storage if localStorage isn't available
|
|
148
|
+
*
|
|
149
|
+
* @returns The best available storage implementation for the current environment
|
|
150
|
+
*/
|
|
151
|
+
export const detectStorage = () => {
|
|
152
|
+
if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
|
|
153
|
+
try {
|
|
154
|
+
// Test if localStorage is actually available (could be disabled)
|
|
155
|
+
localStorage.setItem("__test", "__test");
|
|
156
|
+
localStorage.removeItem("__test");
|
|
157
|
+
return new LocalStorage();
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
console.warn(`localStorage is not available, using in-memory storage instead`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return new MemoryStorage();
|
|
164
|
+
};
|
|
165
|
+
//# sourceMappingURL=sessionStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionStorage.js","sourceRoot":"","sources":["../../src/sessionStorage.ts"],"names":[],"mappings":"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"}
|