naystack 1.8.3 → 1.8.4
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/auth/client.cjs.js +51 -8
- package/dist/auth/client.d.mts +1 -0
- package/dist/auth/client.d.ts +1 -0
- package/dist/auth/client.esm.js +48 -8
- package/dist/auth/email/client.cjs.js +51 -8
- package/dist/auth/email/client.d.mts +1 -0
- package/dist/auth/email/client.d.ts +1 -0
- package/dist/auth/email/client.esm.js +48 -8
- package/dist/auth/email/index.cjs.js +4 -2
- package/dist/auth/email/index.d.mts +1 -0
- package/dist/auth/email/index.d.ts +1 -0
- package/dist/auth/email/index.esm.js +4 -2
- package/dist/auth/email/next.d.mts +1 -0
- package/dist/auth/email/next.d.ts +1 -0
- package/dist/auth/email/routes/delete.cjs.js +4 -2
- package/dist/auth/email/routes/delete.esm.js +4 -2
- package/dist/auth/email/routes/get.cjs.js +4 -2
- package/dist/auth/email/routes/get.esm.js +4 -2
- package/dist/auth/email/routes/post.cjs.js +4 -2
- package/dist/auth/email/routes/post.esm.js +4 -2
- package/dist/auth/email/routes/put.cjs.js +4 -2
- package/dist/auth/email/routes/put.esm.js +4 -2
- package/dist/auth/email/token.cjs.js +4 -2
- package/dist/auth/email/token.d.mts +2 -2
- package/dist/auth/email/token.d.ts +2 -2
- package/dist/auth/email/token.esm.js +4 -2
- package/dist/auth/google/get.cjs.js +3 -1
- package/dist/auth/google/get.esm.js +3 -1
- package/dist/auth/google/index.cjs.js +3 -1
- package/dist/auth/google/index.esm.js +3 -1
- package/dist/auth/index.cjs.js +4 -2
- package/dist/auth/index.d.mts +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.esm.js +4 -2
- package/dist/auth/token-store.cjs.js +120 -0
- package/dist/auth/token-store.d.mts +42 -0
- package/dist/auth/token-store.d.ts +42 -0
- package/dist/auth/token-store.esm.js +90 -0
- package/dist/graphql/client.cjs.js +109 -35
- package/dist/graphql/client.esm.js +102 -29
- package/dist/graphql/links.cjs.js +154 -0
- package/dist/graphql/links.d.mts +14 -0
- package/dist/graphql/links.d.ts +14 -0
- package/dist/graphql/links.esm.js +129 -0
- package/dist/graphql/next.cjs.js +95 -21
- package/dist/graphql/next.esm.js +95 -21
- package/package.json +1 -1
|
@@ -65,7 +65,9 @@ var REFRESH_COOKIE_NAME = "refresh";
|
|
|
65
65
|
|
|
66
66
|
// src/auth/email/token.ts
|
|
67
67
|
function generateRefreshToken(id) {
|
|
68
|
-
return sign({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */)
|
|
68
|
+
return sign({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */), {
|
|
69
|
+
expiresIn: "365d"
|
|
70
|
+
});
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
// src/auth/google/get.ts
|
|
@@ -91,7 +91,9 @@ var REFRESH_COOKIE_NAME = "refresh";
|
|
|
91
91
|
|
|
92
92
|
// src/auth/email/token.ts
|
|
93
93
|
function generateRefreshToken(id) {
|
|
94
|
-
return (0, import_jsonwebtoken.sign)({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */)
|
|
94
|
+
return (0, import_jsonwebtoken.sign)({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */), {
|
|
95
|
+
expiresIn: "365d"
|
|
96
|
+
});
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
// src/auth/google/get.ts
|
|
@@ -65,7 +65,9 @@ var REFRESH_COOKIE_NAME = "refresh";
|
|
|
65
65
|
|
|
66
66
|
// src/auth/email/token.ts
|
|
67
67
|
function generateRefreshToken(id) {
|
|
68
|
-
return sign({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */)
|
|
68
|
+
return sign({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */), {
|
|
69
|
+
expiresIn: "365d"
|
|
70
|
+
});
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
// src/auth/google/get.ts
|
package/dist/auth/index.cjs.js
CHANGED
|
@@ -150,11 +150,13 @@ function getEnv(key, skipCheck) {
|
|
|
150
150
|
// src/auth/email/token.ts
|
|
151
151
|
function generateAccessToken(id) {
|
|
152
152
|
return (0, import_jsonwebtoken.sign)({ id }, getEnv("SIGNING_KEY" /* SIGNING_KEY */), {
|
|
153
|
-
expiresIn: "
|
|
153
|
+
expiresIn: "24h"
|
|
154
154
|
});
|
|
155
155
|
}
|
|
156
156
|
function generateRefreshToken(id) {
|
|
157
|
-
return (0, import_jsonwebtoken.sign)({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */)
|
|
157
|
+
return (0, import_jsonwebtoken.sign)({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */), {
|
|
158
|
+
expiresIn: "365d"
|
|
159
|
+
});
|
|
158
160
|
}
|
|
159
161
|
function getTokenizedResponse(id) {
|
|
160
162
|
const accessToken = id ? generateAccessToken(id) : void 0;
|
package/dist/auth/index.d.mts
CHANGED
package/dist/auth/index.d.ts
CHANGED
package/dist/auth/index.esm.js
CHANGED
|
@@ -104,11 +104,13 @@ function getEnv(key, skipCheck) {
|
|
|
104
104
|
// src/auth/email/token.ts
|
|
105
105
|
function generateAccessToken(id) {
|
|
106
106
|
return sign({ id }, getEnv("SIGNING_KEY" /* SIGNING_KEY */), {
|
|
107
|
-
expiresIn: "
|
|
107
|
+
expiresIn: "24h"
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
function generateRefreshToken(id) {
|
|
111
|
-
return sign({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */)
|
|
111
|
+
return sign({ id }, getEnv("REFRESH_KEY" /* REFRESH_KEY */), {
|
|
112
|
+
expiresIn: "365d"
|
|
113
|
+
});
|
|
112
114
|
}
|
|
113
115
|
function getTokenizedResponse(id) {
|
|
114
116
|
const accessToken = id ? generateAccessToken(id) : void 0;
|
|
@@ -0,0 +1,120 @@
|
|
|
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/auth/token-store.ts
|
|
21
|
+
var token_store_exports = {};
|
|
22
|
+
__export(token_store_exports, {
|
|
23
|
+
getAccessToken: () => getAccessToken,
|
|
24
|
+
refreshAccessToken: () => refreshAccessToken,
|
|
25
|
+
setAccessToken: () => setAccessToken,
|
|
26
|
+
subscribeToAccessToken: () => subscribeToAccessToken
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(token_store_exports);
|
|
29
|
+
|
|
30
|
+
// src/env.ts
|
|
31
|
+
var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
|
|
32
|
+
var getEnvValue = (key) => {
|
|
33
|
+
switch (key) {
|
|
34
|
+
case "NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */:
|
|
35
|
+
return process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT || EXTRA_ENV.GRAPHQL_ENDPOINT;
|
|
36
|
+
case "NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */:
|
|
37
|
+
return process.env.NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT || EXTRA_ENV.EMAIL_AUTH_ENDPOINT;
|
|
38
|
+
case "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT" /* NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT */:
|
|
39
|
+
return process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT || EXTRA_ENV.GOOGLE_AUTH_ENDPOINT;
|
|
40
|
+
case "NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT" /* NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT */:
|
|
41
|
+
return process.env.NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT || EXTRA_ENV.INSTAGRAM_AUTH_ENDPOINT;
|
|
42
|
+
case "NEXT_PUBLIC_FILE_ENDPOINT" /* NEXT_PUBLIC_FILE_ENDPOINT */:
|
|
43
|
+
return process.env.NEXT_PUBLIC_FILE_ENDPOINT || EXTRA_ENV.FILE_ENDPOINT;
|
|
44
|
+
case "NEXT_PUBLIC_BASE_URL" /* NEXT_PUBLIC_BASE_URL */:
|
|
45
|
+
return process.env.NEXT_PUBLIC_BASE_URL || EXTRA_ENV.BASE_URL;
|
|
46
|
+
case "REFRESH_KEY" /* REFRESH_KEY */:
|
|
47
|
+
return process.env.REFRESH_KEY;
|
|
48
|
+
case "SIGNING_KEY" /* SIGNING_KEY */:
|
|
49
|
+
return process.env.SIGNING_KEY;
|
|
50
|
+
case "INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */:
|
|
51
|
+
return process.env.INSTAGRAM_CLIENT_SECRET;
|
|
52
|
+
case "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */:
|
|
53
|
+
return process.env.INSTAGRAM_CLIENT_ID;
|
|
54
|
+
case "GOOGLE_CLIENT_SECRET" /* GOOGLE_CLIENT_SECRET */:
|
|
55
|
+
return process.env.GOOGLE_CLIENT_SECRET;
|
|
56
|
+
case "GOOGLE_CLIENT_ID" /* GOOGLE_CLIENT_ID */:
|
|
57
|
+
return process.env.GOOGLE_CLIENT_ID;
|
|
58
|
+
case "TURNSTILE_KEY" /* TURNSTILE_KEY */:
|
|
59
|
+
return process.env.TURNSTILE_KEY;
|
|
60
|
+
case "S3_ACCESS_KEY_ID" /* S3_ACCESS_KEY_ID */:
|
|
61
|
+
return process.env.S3_ACCESS_KEY_ID;
|
|
62
|
+
case "S3_ACCESS_KEY_SECRET" /* S3_ACCESS_KEY_SECRET */:
|
|
63
|
+
return process.env.S3_ACCESS_KEY_SECRET;
|
|
64
|
+
case "S3_REGION" /* S3_REGION */:
|
|
65
|
+
return process.env.S3_REGION;
|
|
66
|
+
case "S3_BUCKET" /* S3_BUCKET */:
|
|
67
|
+
return process.env.S3_BUCKET;
|
|
68
|
+
case "NODE_ENV" /* NODE_ENV */:
|
|
69
|
+
return process.env.NODE_ENV;
|
|
70
|
+
default:
|
|
71
|
+
return process.env[key];
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
function getEnv(key, skipCheck) {
|
|
75
|
+
const value = getEnvValue(key);
|
|
76
|
+
if (!skipCheck && !value) throw new Error(`${key} is not defined`);
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/auth/token-store.ts
|
|
81
|
+
var currentToken;
|
|
82
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
83
|
+
var inFlightRefresh = null;
|
|
84
|
+
function getAccessToken() {
|
|
85
|
+
return currentToken;
|
|
86
|
+
}
|
|
87
|
+
function setAccessToken(token) {
|
|
88
|
+
if (token === currentToken) return;
|
|
89
|
+
currentToken = token;
|
|
90
|
+
listeners.forEach((listener) => listener(token));
|
|
91
|
+
}
|
|
92
|
+
function subscribeToAccessToken(listener) {
|
|
93
|
+
listeners.add(listener);
|
|
94
|
+
return () => {
|
|
95
|
+
listeners.delete(listener);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function refreshAccessToken() {
|
|
99
|
+
if (inFlightRefresh) return inFlightRefresh;
|
|
100
|
+
inFlightRefresh = (async () => {
|
|
101
|
+
const res = await fetch(
|
|
102
|
+
getEnv("NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */),
|
|
103
|
+
{ credentials: "include" }
|
|
104
|
+
);
|
|
105
|
+
if (!res.ok) throw new Error(`Token refresh failed: ${res.status}`);
|
|
106
|
+
const token = await res.text() || null;
|
|
107
|
+
setAccessToken(token);
|
|
108
|
+
return token;
|
|
109
|
+
})().finally(() => {
|
|
110
|
+
inFlightRefresh = null;
|
|
111
|
+
});
|
|
112
|
+
return inFlightRefresh;
|
|
113
|
+
}
|
|
114
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
115
|
+
0 && (module.exports = {
|
|
116
|
+
getAccessToken,
|
|
117
|
+
refreshAccessToken,
|
|
118
|
+
setAccessToken,
|
|
119
|
+
subscribeToAccessToken
|
|
120
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads the current access token synchronously, outside React.
|
|
3
|
+
* Used by the Apollo auth link; components should use `useToken()`.
|
|
4
|
+
*
|
|
5
|
+
* @returns The access token, `null` when logged out, or `undefined` before the first fetch resolves.
|
|
6
|
+
* @category Auth
|
|
7
|
+
*/
|
|
8
|
+
declare function getAccessToken(): string | null | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Writes the access token and notifies subscribers (which updates `TokenContext`).
|
|
11
|
+
*
|
|
12
|
+
* @param token - New token, or `null` to clear the session.
|
|
13
|
+
* @category Auth
|
|
14
|
+
*/
|
|
15
|
+
declare function setAccessToken(token: string | null | undefined): void;
|
|
16
|
+
/**
|
|
17
|
+
* Subscribes to token changes. `AuthWrapper` uses this to mirror the store into React state.
|
|
18
|
+
*
|
|
19
|
+
* @param listener - Called with the new token on every change.
|
|
20
|
+
* @returns Unsubscribe function.
|
|
21
|
+
* @category Auth
|
|
22
|
+
*/
|
|
23
|
+
declare function subscribeToAccessToken(listener: (token: string | null | undefined) => void): () => void;
|
|
24
|
+
/**
|
|
25
|
+
* Exchanges the httpOnly refresh cookie for a fresh access token via the auth endpoint,
|
|
26
|
+
* and stores the result. Concurrent callers share one request.
|
|
27
|
+
*
|
|
28
|
+
* The auth endpoint answers 200 in both directions, so the body is the signal:
|
|
29
|
+
* a token means the session is alive, an empty body means the refresh cookie is
|
|
30
|
+
* gone or expired and the user is logged out (which clears the token, and in turn
|
|
31
|
+
* trips `ClearStoreOnLogout`).
|
|
32
|
+
*
|
|
33
|
+
* A transport failure (offline, 5xx) rejects **without** clearing the token — a
|
|
34
|
+
* flaky network shouldn't end a valid session.
|
|
35
|
+
*
|
|
36
|
+
* @returns The new access token, or `null` if the session has ended.
|
|
37
|
+
* @throws If the request fails at the transport level or the endpoint returns non-2xx.
|
|
38
|
+
* @category Auth
|
|
39
|
+
*/
|
|
40
|
+
declare function refreshAccessToken(): Promise<string | null>;
|
|
41
|
+
|
|
42
|
+
export { getAccessToken, refreshAccessToken, setAccessToken, subscribeToAccessToken };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads the current access token synchronously, outside React.
|
|
3
|
+
* Used by the Apollo auth link; components should use `useToken()`.
|
|
4
|
+
*
|
|
5
|
+
* @returns The access token, `null` when logged out, or `undefined` before the first fetch resolves.
|
|
6
|
+
* @category Auth
|
|
7
|
+
*/
|
|
8
|
+
declare function getAccessToken(): string | null | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Writes the access token and notifies subscribers (which updates `TokenContext`).
|
|
11
|
+
*
|
|
12
|
+
* @param token - New token, or `null` to clear the session.
|
|
13
|
+
* @category Auth
|
|
14
|
+
*/
|
|
15
|
+
declare function setAccessToken(token: string | null | undefined): void;
|
|
16
|
+
/**
|
|
17
|
+
* Subscribes to token changes. `AuthWrapper` uses this to mirror the store into React state.
|
|
18
|
+
*
|
|
19
|
+
* @param listener - Called with the new token on every change.
|
|
20
|
+
* @returns Unsubscribe function.
|
|
21
|
+
* @category Auth
|
|
22
|
+
*/
|
|
23
|
+
declare function subscribeToAccessToken(listener: (token: string | null | undefined) => void): () => void;
|
|
24
|
+
/**
|
|
25
|
+
* Exchanges the httpOnly refresh cookie for a fresh access token via the auth endpoint,
|
|
26
|
+
* and stores the result. Concurrent callers share one request.
|
|
27
|
+
*
|
|
28
|
+
* The auth endpoint answers 200 in both directions, so the body is the signal:
|
|
29
|
+
* a token means the session is alive, an empty body means the refresh cookie is
|
|
30
|
+
* gone or expired and the user is logged out (which clears the token, and in turn
|
|
31
|
+
* trips `ClearStoreOnLogout`).
|
|
32
|
+
*
|
|
33
|
+
* A transport failure (offline, 5xx) rejects **without** clearing the token — a
|
|
34
|
+
* flaky network shouldn't end a valid session.
|
|
35
|
+
*
|
|
36
|
+
* @returns The new access token, or `null` if the session has ended.
|
|
37
|
+
* @throws If the request fails at the transport level or the endpoint returns non-2xx.
|
|
38
|
+
* @category Auth
|
|
39
|
+
*/
|
|
40
|
+
declare function refreshAccessToken(): Promise<string | null>;
|
|
41
|
+
|
|
42
|
+
export { getAccessToken, refreshAccessToken, setAccessToken, subscribeToAccessToken };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// src/env.ts
|
|
2
|
+
var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
|
|
3
|
+
var getEnvValue = (key) => {
|
|
4
|
+
switch (key) {
|
|
5
|
+
case "NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */:
|
|
6
|
+
return process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT || EXTRA_ENV.GRAPHQL_ENDPOINT;
|
|
7
|
+
case "NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */:
|
|
8
|
+
return process.env.NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT || EXTRA_ENV.EMAIL_AUTH_ENDPOINT;
|
|
9
|
+
case "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT" /* NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT */:
|
|
10
|
+
return process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT || EXTRA_ENV.GOOGLE_AUTH_ENDPOINT;
|
|
11
|
+
case "NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT" /* NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT */:
|
|
12
|
+
return process.env.NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT || EXTRA_ENV.INSTAGRAM_AUTH_ENDPOINT;
|
|
13
|
+
case "NEXT_PUBLIC_FILE_ENDPOINT" /* NEXT_PUBLIC_FILE_ENDPOINT */:
|
|
14
|
+
return process.env.NEXT_PUBLIC_FILE_ENDPOINT || EXTRA_ENV.FILE_ENDPOINT;
|
|
15
|
+
case "NEXT_PUBLIC_BASE_URL" /* NEXT_PUBLIC_BASE_URL */:
|
|
16
|
+
return process.env.NEXT_PUBLIC_BASE_URL || EXTRA_ENV.BASE_URL;
|
|
17
|
+
case "REFRESH_KEY" /* REFRESH_KEY */:
|
|
18
|
+
return process.env.REFRESH_KEY;
|
|
19
|
+
case "SIGNING_KEY" /* SIGNING_KEY */:
|
|
20
|
+
return process.env.SIGNING_KEY;
|
|
21
|
+
case "INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */:
|
|
22
|
+
return process.env.INSTAGRAM_CLIENT_SECRET;
|
|
23
|
+
case "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */:
|
|
24
|
+
return process.env.INSTAGRAM_CLIENT_ID;
|
|
25
|
+
case "GOOGLE_CLIENT_SECRET" /* GOOGLE_CLIENT_SECRET */:
|
|
26
|
+
return process.env.GOOGLE_CLIENT_SECRET;
|
|
27
|
+
case "GOOGLE_CLIENT_ID" /* GOOGLE_CLIENT_ID */:
|
|
28
|
+
return process.env.GOOGLE_CLIENT_ID;
|
|
29
|
+
case "TURNSTILE_KEY" /* TURNSTILE_KEY */:
|
|
30
|
+
return process.env.TURNSTILE_KEY;
|
|
31
|
+
case "S3_ACCESS_KEY_ID" /* S3_ACCESS_KEY_ID */:
|
|
32
|
+
return process.env.S3_ACCESS_KEY_ID;
|
|
33
|
+
case "S3_ACCESS_KEY_SECRET" /* S3_ACCESS_KEY_SECRET */:
|
|
34
|
+
return process.env.S3_ACCESS_KEY_SECRET;
|
|
35
|
+
case "S3_REGION" /* S3_REGION */:
|
|
36
|
+
return process.env.S3_REGION;
|
|
37
|
+
case "S3_BUCKET" /* S3_BUCKET */:
|
|
38
|
+
return process.env.S3_BUCKET;
|
|
39
|
+
case "NODE_ENV" /* NODE_ENV */:
|
|
40
|
+
return process.env.NODE_ENV;
|
|
41
|
+
default:
|
|
42
|
+
return process.env[key];
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
function getEnv(key, skipCheck) {
|
|
46
|
+
const value = getEnvValue(key);
|
|
47
|
+
if (!skipCheck && !value) throw new Error(`${key} is not defined`);
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/auth/token-store.ts
|
|
52
|
+
var currentToken;
|
|
53
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
54
|
+
var inFlightRefresh = null;
|
|
55
|
+
function getAccessToken() {
|
|
56
|
+
return currentToken;
|
|
57
|
+
}
|
|
58
|
+
function setAccessToken(token) {
|
|
59
|
+
if (token === currentToken) return;
|
|
60
|
+
currentToken = token;
|
|
61
|
+
listeners.forEach((listener) => listener(token));
|
|
62
|
+
}
|
|
63
|
+
function subscribeToAccessToken(listener) {
|
|
64
|
+
listeners.add(listener);
|
|
65
|
+
return () => {
|
|
66
|
+
listeners.delete(listener);
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function refreshAccessToken() {
|
|
70
|
+
if (inFlightRefresh) return inFlightRefresh;
|
|
71
|
+
inFlightRefresh = (async () => {
|
|
72
|
+
const res = await fetch(
|
|
73
|
+
getEnv("NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */),
|
|
74
|
+
{ credentials: "include" }
|
|
75
|
+
);
|
|
76
|
+
if (!res.ok) throw new Error(`Token refresh failed: ${res.status}`);
|
|
77
|
+
const token = await res.text() || null;
|
|
78
|
+
setAccessToken(token);
|
|
79
|
+
return token;
|
|
80
|
+
})().finally(() => {
|
|
81
|
+
inFlightRefresh = null;
|
|
82
|
+
});
|
|
83
|
+
return inFlightRefresh;
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
getAccessToken,
|
|
87
|
+
refreshAccessToken,
|
|
88
|
+
setAccessToken,
|
|
89
|
+
subscribeToAccessToken
|
|
90
|
+
};
|
|
@@ -37,10 +37,34 @@ __export(client_exports, {
|
|
|
37
37
|
useAuthQuery: () => useAuthQuery
|
|
38
38
|
});
|
|
39
39
|
module.exports = __toCommonJS(client_exports);
|
|
40
|
-
var
|
|
41
|
-
var
|
|
40
|
+
var import_client4 = require("@apollo/client");
|
|
41
|
+
var import_client5 = require("naystack/auth/client");
|
|
42
42
|
var import_react2 = __toESM(require("react"));
|
|
43
43
|
|
|
44
|
+
// src/graphql/clear-store.tsx
|
|
45
|
+
var import_client = require("@apollo/client");
|
|
46
|
+
var import_client2 = require("naystack/auth/client");
|
|
47
|
+
var import_react = require("react");
|
|
48
|
+
function ClearStoreOnLogout() {
|
|
49
|
+
const client = (0, import_client.useApolloClient)();
|
|
50
|
+
const token = (0, import_client2.useToken)();
|
|
51
|
+
const hadToken = (0, import_react.useRef)(false);
|
|
52
|
+
(0, import_react.useEffect)(() => {
|
|
53
|
+
if (token) {
|
|
54
|
+
hadToken.current = true;
|
|
55
|
+
} else if (token === null && hadToken.current) {
|
|
56
|
+
hadToken.current = false;
|
|
57
|
+
void client.clearStore();
|
|
58
|
+
}
|
|
59
|
+
}, [client, token]);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/graphql/links.ts
|
|
64
|
+
var import_client3 = require("@apollo/client");
|
|
65
|
+
var import_context = require("@apollo/client/link/context");
|
|
66
|
+
var import_error = require("@apollo/client/link/error");
|
|
67
|
+
|
|
44
68
|
// src/env.ts
|
|
45
69
|
var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
|
|
46
70
|
var getEnvValue = (key) => {
|
|
@@ -91,32 +115,83 @@ function getEnv(key, skipCheck) {
|
|
|
91
115
|
return value;
|
|
92
116
|
}
|
|
93
117
|
|
|
94
|
-
// src/
|
|
95
|
-
var
|
|
96
|
-
var
|
|
97
|
-
var
|
|
98
|
-
function
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
118
|
+
// src/auth/token-store.ts
|
|
119
|
+
var currentToken;
|
|
120
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
121
|
+
var inFlightRefresh = null;
|
|
122
|
+
function getAccessToken() {
|
|
123
|
+
return currentToken;
|
|
124
|
+
}
|
|
125
|
+
function setAccessToken(token) {
|
|
126
|
+
if (token === currentToken) return;
|
|
127
|
+
currentToken = token;
|
|
128
|
+
listeners.forEach((listener) => listener(token));
|
|
129
|
+
}
|
|
130
|
+
function refreshAccessToken() {
|
|
131
|
+
if (inFlightRefresh) return inFlightRefresh;
|
|
132
|
+
inFlightRefresh = (async () => {
|
|
133
|
+
const res = await fetch(
|
|
134
|
+
getEnv("NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */),
|
|
135
|
+
{ credentials: "include" }
|
|
136
|
+
);
|
|
137
|
+
if (!res.ok) throw new Error(`Token refresh failed: ${res.status}`);
|
|
138
|
+
const token = await res.text() || null;
|
|
139
|
+
setAccessToken(token);
|
|
140
|
+
return token;
|
|
141
|
+
})().finally(() => {
|
|
142
|
+
inFlightRefresh = null;
|
|
143
|
+
});
|
|
144
|
+
return inFlightRefresh;
|
|
111
145
|
}
|
|
112
146
|
|
|
113
|
-
// src/graphql/
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
147
|
+
// src/graphql/links.ts
|
|
148
|
+
var RETRY_CONTEXT_KEY = "__naystackRetried";
|
|
149
|
+
function isExpiredTokenError(error) {
|
|
150
|
+
return error.extensions?.code === "UNAUTHENTICATED";
|
|
151
|
+
}
|
|
152
|
+
var authLink = (0, import_context.setContext)((_, previousContext) => {
|
|
153
|
+
const token = getAccessToken();
|
|
154
|
+
if (!token || previousContext.credentials === "include")
|
|
155
|
+
return previousContext;
|
|
156
|
+
return {
|
|
157
|
+
...previousContext,
|
|
158
|
+
headers: {
|
|
159
|
+
...previousContext.headers,
|
|
160
|
+
authorization: `Bearer ${token}`
|
|
161
|
+
},
|
|
162
|
+
credentials: "omit"
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
var refreshLink = (0, import_error.onError)(({ graphQLErrors, operation, forward }) => {
|
|
166
|
+
if (!graphQLErrors?.some(isExpiredTokenError)) return;
|
|
167
|
+
if (operation.getContext()[RETRY_CONTEXT_KEY]) return;
|
|
168
|
+
return (0, import_client3.fromPromise)(
|
|
169
|
+
// A failed refresh still replays once: the retry reproduces the original
|
|
170
|
+
// error for the caller instead of surfacing the refresh's error in its place.
|
|
171
|
+
refreshAccessToken().catch(() => null)
|
|
172
|
+
).flatMap(() => {
|
|
173
|
+
operation.setContext((previousContext) => ({
|
|
174
|
+
...previousContext,
|
|
175
|
+
[RETRY_CONTEXT_KEY]: true
|
|
176
|
+
}));
|
|
177
|
+
return forward(operation);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
function makeAuthLink() {
|
|
181
|
+
return import_client3.ApolloLink.from([
|
|
182
|
+
refreshLink,
|
|
183
|
+
authLink,
|
|
184
|
+
new import_client3.HttpLink({
|
|
118
185
|
uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
|
|
119
186
|
})
|
|
187
|
+
]);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/graphql/client.tsx
|
|
191
|
+
function makeClient(cacheConfig) {
|
|
192
|
+
return new import_client4.ApolloClient({
|
|
193
|
+
cache: new import_client4.InMemoryCache(cacheConfig),
|
|
194
|
+
link: makeAuthLink()
|
|
120
195
|
});
|
|
121
196
|
}
|
|
122
197
|
var ApolloWrapper = ({
|
|
@@ -125,7 +200,7 @@ var ApolloWrapper = ({
|
|
|
125
200
|
}) => {
|
|
126
201
|
const clientRef = (0, import_react2.useRef)(null);
|
|
127
202
|
if (!clientRef.current) clientRef.current = makeClient(cacheConfig);
|
|
128
|
-
return /* @__PURE__ */ import_react2.default.createElement(
|
|
203
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_client4.ApolloProvider, { client: clientRef.current }, /* @__PURE__ */ import_react2.default.createElement(ClearStoreOnLogout, null), children);
|
|
129
204
|
};
|
|
130
205
|
var tokenContext = (token) => {
|
|
131
206
|
if (!token) return void 0;
|
|
@@ -137,7 +212,7 @@ var tokenContext = (token) => {
|
|
|
137
212
|
};
|
|
138
213
|
};
|
|
139
214
|
function useAuthQuery(query, variables, options) {
|
|
140
|
-
const [
|
|
215
|
+
const [fetch2, result] = (0, import_client4.useLazyQuery)(query, {
|
|
141
216
|
fetchPolicy: "no-cache",
|
|
142
217
|
...options
|
|
143
218
|
});
|
|
@@ -146,7 +221,7 @@ function useAuthQuery(query, variables, options) {
|
|
|
146
221
|
const serialized = JSON.stringify(variables);
|
|
147
222
|
if (variables && prevVarsRef.current !== serialized) {
|
|
148
223
|
prevVarsRef.current = serialized;
|
|
149
|
-
void
|
|
224
|
+
void fetch2({
|
|
150
225
|
// @ts-expect-error -- to allow dynamic props
|
|
151
226
|
variables: { input: variables },
|
|
152
227
|
context: {
|
|
@@ -154,29 +229,28 @@ function useAuthQuery(query, variables, options) {
|
|
|
154
229
|
}
|
|
155
230
|
});
|
|
156
231
|
}
|
|
157
|
-
}, [
|
|
232
|
+
}, [fetch2, variables]);
|
|
158
233
|
const reFetch = (0, import_react2.useCallback)(
|
|
159
|
-
(input) =>
|
|
234
|
+
(input) => fetch2({
|
|
160
235
|
// @ts-expect-error -- to allow dynamic props
|
|
161
236
|
variables: { input },
|
|
162
237
|
context: {
|
|
163
238
|
credentials: `include`
|
|
164
239
|
}
|
|
165
240
|
}),
|
|
166
|
-
[
|
|
241
|
+
[fetch2]
|
|
167
242
|
);
|
|
168
243
|
return [reFetch, result];
|
|
169
244
|
}
|
|
170
245
|
function useAuthMutation(mutation, options) {
|
|
171
|
-
const token = (0,
|
|
172
|
-
const [mutate, result] = (0,
|
|
246
|
+
const token = (0, import_client5.useToken)();
|
|
247
|
+
const [mutate, result] = (0, import_client4.useMutation)(mutation, options);
|
|
173
248
|
const method = (0, import_react2.useCallback)(
|
|
174
249
|
(input) => mutate({
|
|
175
250
|
// @ts-expect-error -- to allow dynamic props
|
|
176
|
-
variables: { input }
|
|
177
|
-
context: tokenContext(token)
|
|
251
|
+
variables: { input }
|
|
178
252
|
}),
|
|
179
|
-
[
|
|
253
|
+
[mutate]
|
|
180
254
|
);
|
|
181
255
|
return [method, { ...result, hasAuth: !!token }];
|
|
182
256
|
}
|