naystack 1.5.25 → 1.5.27

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.
@@ -44,6 +44,9 @@ __export(client_exports, {
44
44
  module.exports = __toCommonJS(client_exports);
45
45
  var import_react = __toESM(require("react"));
46
46
 
47
+ // src/auth/constants.ts
48
+ var REFRESH_COOKIE_NAME = "refresh";
49
+
47
50
  // src/env.ts
48
51
  var getEnvValue = (key) => {
49
52
  switch (key) {
@@ -95,19 +98,33 @@ function getEnv(key, skipCheck) {
95
98
 
96
99
  // src/auth/email/client.tsx
97
100
  var TokenContext = (0, import_react.createContext)({
98
- token: null,
101
+ token: void 0,
99
102
  setToken: () => null
100
103
  });
101
- var AuthWrapper = ({ children }) => {
102
- const [token, setToken] = (0, import_react.useState)(null);
104
+ var AuthWrapper = ({
105
+ children,
106
+ onTokenUpdate
107
+ }) => {
108
+ const [token, setToken] = (0, import_react.useState)();
109
+ (0, import_react.useEffect)(() => {
110
+ if (onTokenUpdate && token !== void 0) {
111
+ onTokenUpdate(token);
112
+ }
113
+ }, [token]);
103
114
  return /* @__PURE__ */ import_react.default.createElement(TokenContext.Provider, { value: { token, setToken } }, children);
104
115
  };
105
- function useAuthFetch() {
116
+ function useAuthFetch(getRefreshToken) {
106
117
  const setToken = useSetToken();
107
- (0, import_react.useEffect)(() => {
118
+ const fetchToken = async () => {
108
119
  fetch(getEnv("NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */), {
109
- credentials: "include"
120
+ credentials: "include",
121
+ body: getRefreshToken ? JSON.stringify({
122
+ [REFRESH_COOKIE_NAME]: await getRefreshToken()
123
+ }) : void 0
110
124
  }).then((res) => res.json()).then((data) => setToken(data.accessToken));
125
+ };
126
+ (0, import_react.useEffect)(() => {
127
+ fetchToken();
111
128
  }, []);
112
129
  }
113
130
  function AuthApply({ data }) {
@@ -5,8 +5,8 @@ import React__default, { Dispatch, SetStateAction } from 'react';
5
5
  * @category Auth
6
6
  */
7
7
  declare const TokenContext: React__default.Context<{
8
- token: string | null;
9
- setToken: Dispatch<SetStateAction<string | null>>;
8
+ token: string | null | undefined;
9
+ setToken: Dispatch<SetStateAction<string | null | undefined>>;
10
10
  }>;
11
11
  /**
12
12
  * Provider that fetches the current access token from your auth endpoint and exposes it via TokenContext.
@@ -39,10 +39,11 @@ declare const TokenContext: React__default.Context<{
39
39
  *
40
40
  * @category Auth
41
41
  */
42
- declare const AuthWrapper: ({ children }: {
42
+ declare const AuthWrapper: ({ children, onTokenUpdate, }: {
43
43
  children: React__default.ReactNode;
44
+ onTokenUpdate?: (token: string | null) => void;
44
45
  }) => React__default.JSX.Element;
45
- declare function useAuthFetch(): void;
46
+ declare function useAuthFetch(getRefreshToken?: () => Promise<string>): void;
46
47
  declare function AuthApply({ data }: {
47
48
  data?: string | null;
48
49
  }): null;
@@ -73,7 +74,7 @@ declare function AuthApply({ data }: {
73
74
  *
74
75
  * @category Auth
75
76
  */
76
- declare function useToken(): string | null;
77
+ declare function useToken(): string | null | undefined;
77
78
  /**
78
79
  * Returns the setter for the access token in TokenContext. Use to update token after login/signup or clear it on logout.
79
80
  * Must be used inside `AuthWrapper`. Typically you won't need this directly — use `useLogin`, `useSignUp`, and `useLogout` instead.
@@ -82,7 +83,7 @@ declare function useToken(): string | null;
82
83
  *
83
84
  * @category Auth
84
85
  */
85
- declare function useSetToken(): React__default.Dispatch<React__default.SetStateAction<string | null>>;
86
+ declare function useSetToken(): React__default.Dispatch<React__default.SetStateAction<string | null | undefined>>;
86
87
  /**
87
88
  * Returns a sign-up function that POSTs to the auth endpoint with credentials. On success, the response's
88
89
  * `accessToken` is stored and the token context updates automatically.
@@ -5,8 +5,8 @@ import React__default, { Dispatch, SetStateAction } from 'react';
5
5
  * @category Auth
6
6
  */
7
7
  declare const TokenContext: React__default.Context<{
8
- token: string | null;
9
- setToken: Dispatch<SetStateAction<string | null>>;
8
+ token: string | null | undefined;
9
+ setToken: Dispatch<SetStateAction<string | null | undefined>>;
10
10
  }>;
11
11
  /**
12
12
  * Provider that fetches the current access token from your auth endpoint and exposes it via TokenContext.
@@ -39,10 +39,11 @@ declare const TokenContext: React__default.Context<{
39
39
  *
40
40
  * @category Auth
41
41
  */
42
- declare const AuthWrapper: ({ children }: {
42
+ declare const AuthWrapper: ({ children, onTokenUpdate, }: {
43
43
  children: React__default.ReactNode;
44
+ onTokenUpdate?: (token: string | null) => void;
44
45
  }) => React__default.JSX.Element;
45
- declare function useAuthFetch(): void;
46
+ declare function useAuthFetch(getRefreshToken?: () => Promise<string>): void;
46
47
  declare function AuthApply({ data }: {
47
48
  data?: string | null;
48
49
  }): null;
@@ -73,7 +74,7 @@ declare function AuthApply({ data }: {
73
74
  *
74
75
  * @category Auth
75
76
  */
76
- declare function useToken(): string | null;
77
+ declare function useToken(): string | null | undefined;
77
78
  /**
78
79
  * Returns the setter for the access token in TokenContext. Use to update token after login/signup or clear it on logout.
79
80
  * Must be used inside `AuthWrapper`. Typically you won't need this directly — use `useLogin`, `useSignUp`, and `useLogout` instead.
@@ -82,7 +83,7 @@ declare function useToken(): string | null;
82
83
  *
83
84
  * @category Auth
84
85
  */
85
- declare function useSetToken(): React__default.Dispatch<React__default.SetStateAction<string | null>>;
86
+ declare function useSetToken(): React__default.Dispatch<React__default.SetStateAction<string | null | undefined>>;
86
87
  /**
87
88
  * Returns a sign-up function that POSTs to the auth endpoint with credentials. On success, the response's
88
89
  * `accessToken` is stored and the token context updates automatically.
@@ -9,6 +9,9 @@ import React, {
9
9
  useState
10
10
  } from "react";
11
11
 
12
+ // src/auth/constants.ts
13
+ var REFRESH_COOKIE_NAME = "refresh";
14
+
12
15
  // src/env.ts
13
16
  var getEnvValue = (key) => {
14
17
  switch (key) {
@@ -60,19 +63,33 @@ function getEnv(key, skipCheck) {
60
63
 
61
64
  // src/auth/email/client.tsx
62
65
  var TokenContext = createContext({
63
- token: null,
66
+ token: void 0,
64
67
  setToken: () => null
65
68
  });
66
- var AuthWrapper = ({ children }) => {
67
- const [token, setToken] = useState(null);
69
+ var AuthWrapper = ({
70
+ children,
71
+ onTokenUpdate
72
+ }) => {
73
+ const [token, setToken] = useState();
74
+ useEffect(() => {
75
+ if (onTokenUpdate && token !== void 0) {
76
+ onTokenUpdate(token);
77
+ }
78
+ }, [token]);
68
79
  return /* @__PURE__ */ React.createElement(TokenContext.Provider, { value: { token, setToken } }, children);
69
80
  };
70
- function useAuthFetch() {
81
+ function useAuthFetch(getRefreshToken) {
71
82
  const setToken = useSetToken();
72
- useEffect(() => {
83
+ const fetchToken = async () => {
73
84
  fetch(getEnv("NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */), {
74
- credentials: "include"
85
+ credentials: "include",
86
+ body: getRefreshToken ? JSON.stringify({
87
+ [REFRESH_COOKIE_NAME]: await getRefreshToken()
88
+ }) : void 0
75
89
  }).then((res) => res.json()).then((data) => setToken(data.accessToken));
90
+ };
91
+ useEffect(() => {
92
+ fetchToken();
76
93
  }, []);
77
94
  }
78
95
  function AuthApply({ data }) {
@@ -36,6 +36,7 @@ __export(email_exports, {
36
36
  getEmailAuthRoutes: () => getEmailAuthRoutes
37
37
  });
38
38
  module.exports = __toCommonJS(email_exports);
39
+ var import_server4 = require("next/server");
39
40
 
40
41
  // src/auth/email/token.ts
41
42
  var import_bcryptjs = require("bcryptjs");
@@ -242,7 +243,9 @@ var getDeleteRoute = (options) => async (req) => {
242
243
  // src/auth/email/routes/get.ts
243
244
  var getGetRoute = (options) => async (req) => {
244
245
  const refresh = req.cookies.get(REFRESH_COOKIE_NAME)?.value;
245
- const userID = getUserIdFromRefreshToken(refresh);
246
+ const requestBody = refresh ? null : await req.json();
247
+ const bodyRefresh = requestBody?.[REFRESH_COOKIE_NAME];
248
+ const userID = getUserIdFromRefreshToken(refresh || bodyRefresh);
246
249
  if (userID) {
247
250
  if (options.onRefresh) {
248
251
  const body = await req.json();
@@ -366,12 +369,52 @@ function AuthFetch() {
366
369
  }
367
370
 
368
371
  // src/auth/email/index.ts
372
+ function getCorsHeaders(origin, allowedOrigins) {
373
+ if (!origin || !allowedOrigins.includes(origin)) return null;
374
+ return {
375
+ "Access-Control-Allow-Origin": origin,
376
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
377
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
378
+ "Access-Control-Allow-Credentials": "true"
379
+ };
380
+ }
381
+ function withCors(handler, allowedOrigins) {
382
+ if (!allowedOrigins?.length) return handler;
383
+ return ((req) => {
384
+ return handler(req).then((response) => {
385
+ if (!response) return response;
386
+ const corsHeaders = getCorsHeaders(
387
+ req.headers.get("origin"),
388
+ allowedOrigins
389
+ );
390
+ if (corsHeaders) {
391
+ Object.entries(corsHeaders).forEach(([key, value]) => {
392
+ response.headers.set(key, value);
393
+ });
394
+ }
395
+ return response;
396
+ });
397
+ });
398
+ }
369
399
  function getEmailAuthRoutes(options) {
400
+ const { allowedOrigins } = options;
370
401
  return {
371
- GET: getGetRoute(options),
372
- POST: getPostRoute(options),
373
- PUT: getPutRoute(options),
374
- DELETE: getDeleteRoute(options)
402
+ GET: withCors(getGetRoute(options), allowedOrigins),
403
+ POST: withCors(getPostRoute(options), allowedOrigins),
404
+ PUT: withCors(getPutRoute(options), allowedOrigins),
405
+ DELETE: withCors(getDeleteRoute(options), allowedOrigins),
406
+ ...allowedOrigins?.length ? {
407
+ OPTIONS: (req) => {
408
+ const corsHeaders = getCorsHeaders(
409
+ req.headers.get("origin"),
410
+ allowedOrigins
411
+ );
412
+ return new import_server4.NextResponse(null, {
413
+ status: 204,
414
+ headers: corsHeaders ?? void 0
415
+ });
416
+ }
417
+ } : {}
375
418
  };
376
419
  }
377
420
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,4 +1,4 @@
1
- import * as next_server from 'next/server';
1
+ import { NextRequest, NextResponse } from 'next/server';
2
2
  import { InitRoutesOptions } from './types.mjs';
3
3
  export { default as AuthFetch } from './server.mjs';
4
4
  export { checkAuthStatus } from './token.mjs';
@@ -48,13 +48,14 @@ import '../../graphql/types.mjs';
48
48
  * @category Auth
49
49
  */
50
50
  declare function getEmailAuthRoutes(options: InitRoutesOptions): {
51
- GET: (req: next_server.NextRequest) => Promise<next_server.NextResponse<{
51
+ OPTIONS?: ((req: NextRequest) => NextResponse<unknown>) | undefined;
52
+ GET: (req: NextRequest) => Promise<NextResponse<{
52
53
  accessToken: string | undefined;
53
54
  refreshToken: string | undefined;
54
55
  }>>;
55
- POST: (req: next_server.NextRequest) => Promise<next_server.NextResponse<unknown> | undefined>;
56
- PUT: (req: next_server.NextRequest) => Promise<next_server.NextResponse<unknown> | undefined>;
57
- DELETE: (req: next_server.NextRequest) => Promise<next_server.NextResponse<{
56
+ POST: (req: NextRequest) => Promise<NextResponse<unknown> | undefined>;
57
+ PUT: (req: NextRequest) => Promise<NextResponse<unknown> | undefined>;
58
+ DELETE: (req: NextRequest) => Promise<NextResponse<{
58
59
  accessToken: string | undefined;
59
60
  refreshToken: string | undefined;
60
61
  }>>;
@@ -1,4 +1,4 @@
1
- import * as next_server from 'next/server';
1
+ import { NextRequest, NextResponse } from 'next/server';
2
2
  import { InitRoutesOptions } from './types.js';
3
3
  export { default as AuthFetch } from './server.js';
4
4
  export { checkAuthStatus } from './token.js';
@@ -48,13 +48,14 @@ import '../../graphql/types.js';
48
48
  * @category Auth
49
49
  */
50
50
  declare function getEmailAuthRoutes(options: InitRoutesOptions): {
51
- GET: (req: next_server.NextRequest) => Promise<next_server.NextResponse<{
51
+ OPTIONS?: ((req: NextRequest) => NextResponse<unknown>) | undefined;
52
+ GET: (req: NextRequest) => Promise<NextResponse<{
52
53
  accessToken: string | undefined;
53
54
  refreshToken: string | undefined;
54
55
  }>>;
55
- POST: (req: next_server.NextRequest) => Promise<next_server.NextResponse<unknown> | undefined>;
56
- PUT: (req: next_server.NextRequest) => Promise<next_server.NextResponse<unknown> | undefined>;
57
- DELETE: (req: next_server.NextRequest) => Promise<next_server.NextResponse<{
56
+ POST: (req: NextRequest) => Promise<NextResponse<unknown> | undefined>;
57
+ PUT: (req: NextRequest) => Promise<NextResponse<unknown> | undefined>;
58
+ DELETE: (req: NextRequest) => Promise<NextResponse<{
58
59
  accessToken: string | undefined;
59
60
  refreshToken: string | undefined;
60
61
  }>>;
@@ -1,3 +1,6 @@
1
+ // src/auth/email/index.ts
2
+ import { NextResponse as NextResponse3 } from "next/server";
3
+
1
4
  // src/auth/email/token.ts
2
5
  import { compare } from "bcryptjs";
3
6
  import { JsonWebTokenError, sign, verify } from "jsonwebtoken";
@@ -203,7 +206,9 @@ var getDeleteRoute = (options) => async (req) => {
203
206
  // src/auth/email/routes/get.ts
204
207
  var getGetRoute = (options) => async (req) => {
205
208
  const refresh = req.cookies.get(REFRESH_COOKIE_NAME)?.value;
206
- const userID = getUserIdFromRefreshToken(refresh);
209
+ const requestBody = refresh ? null : await req.json();
210
+ const bodyRefresh = requestBody?.[REFRESH_COOKIE_NAME];
211
+ const userID = getUserIdFromRefreshToken(refresh || bodyRefresh);
207
212
  if (userID) {
208
213
  if (options.onRefresh) {
209
214
  const body = await req.json();
@@ -331,12 +336,52 @@ function AuthFetch() {
331
336
  }
332
337
 
333
338
  // src/auth/email/index.ts
339
+ function getCorsHeaders(origin, allowedOrigins) {
340
+ if (!origin || !allowedOrigins.includes(origin)) return null;
341
+ return {
342
+ "Access-Control-Allow-Origin": origin,
343
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
344
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
345
+ "Access-Control-Allow-Credentials": "true"
346
+ };
347
+ }
348
+ function withCors(handler, allowedOrigins) {
349
+ if (!allowedOrigins?.length) return handler;
350
+ return ((req) => {
351
+ return handler(req).then((response) => {
352
+ if (!response) return response;
353
+ const corsHeaders = getCorsHeaders(
354
+ req.headers.get("origin"),
355
+ allowedOrigins
356
+ );
357
+ if (corsHeaders) {
358
+ Object.entries(corsHeaders).forEach(([key, value]) => {
359
+ response.headers.set(key, value);
360
+ });
361
+ }
362
+ return response;
363
+ });
364
+ });
365
+ }
334
366
  function getEmailAuthRoutes(options) {
367
+ const { allowedOrigins } = options;
335
368
  return {
336
- GET: getGetRoute(options),
337
- POST: getPostRoute(options),
338
- PUT: getPutRoute(options),
339
- DELETE: getDeleteRoute(options)
369
+ GET: withCors(getGetRoute(options), allowedOrigins),
370
+ POST: withCors(getPostRoute(options), allowedOrigins),
371
+ PUT: withCors(getPutRoute(options), allowedOrigins),
372
+ DELETE: withCors(getDeleteRoute(options), allowedOrigins),
373
+ ...allowedOrigins?.length ? {
374
+ OPTIONS: (req) => {
375
+ const corsHeaders = getCorsHeaders(
376
+ req.headers.get("origin"),
377
+ allowedOrigins
378
+ );
379
+ return new NextResponse3(null, {
380
+ status: 204,
381
+ headers: corsHeaders ?? void 0
382
+ });
383
+ }
384
+ } : {}
340
385
  };
341
386
  }
342
387
  export {
@@ -124,7 +124,9 @@ function getUserIdFromRefreshToken(refreshToken) {
124
124
  // src/auth/email/routes/get.ts
125
125
  var getGetRoute = (options) => async (req) => {
126
126
  const refresh = req.cookies.get(REFRESH_COOKIE_NAME)?.value;
127
- const userID = getUserIdFromRefreshToken(refresh);
127
+ const requestBody = refresh ? null : await req.json();
128
+ const bodyRefresh = requestBody?.[REFRESH_COOKIE_NAME];
129
+ const userID = getUserIdFromRefreshToken(refresh || bodyRefresh);
128
130
  if (userID) {
129
131
  if (options.onRefresh) {
130
132
  const body = await req.json();
@@ -98,7 +98,9 @@ function getUserIdFromRefreshToken(refreshToken) {
98
98
  // src/auth/email/routes/get.ts
99
99
  var getGetRoute = (options) => async (req) => {
100
100
  const refresh = req.cookies.get(REFRESH_COOKIE_NAME)?.value;
101
- const userID = getUserIdFromRefreshToken(refresh);
101
+ const requestBody = refresh ? null : await req.json();
102
+ const bodyRefresh = requestBody?.[REFRESH_COOKIE_NAME];
103
+ const userID = getUserIdFromRefreshToken(refresh || bodyRefresh);
102
104
  if (userID) {
103
105
  if (options.onRefresh) {
104
106
  const body = await req.json();
@@ -31,6 +31,7 @@ type InitRoutesOptions = {
31
31
  onLogin?: (userId: number | null, body: any) => Promise<void>;
32
32
  onRefresh?: (userId: number | null, body: any) => Promise<void>;
33
33
  onLogout?: (userId: number | null, body: any) => Promise<void>;
34
+ allowedOrigins?: string[];
34
35
  };
35
36
 
36
37
  export type { InitRoutesOptions };
@@ -31,6 +31,7 @@ type InitRoutesOptions = {
31
31
  onLogin?: (userId: number | null, body: any) => Promise<void>;
32
32
  onRefresh?: (userId: number | null, body: any) => Promise<void>;
33
33
  onLogout?: (userId: number | null, body: any) => Promise<void>;
34
+ allowedOrigins?: string[];
34
35
  };
35
36
 
36
37
  export type { InitRoutesOptions };
@@ -41,6 +41,9 @@ __export(auth_exports, {
41
41
  });
42
42
  module.exports = __toCommonJS(auth_exports);
43
43
 
44
+ // src/auth/email/index.ts
45
+ var import_server4 = require("next/server");
46
+
44
47
  // src/auth/email/token.ts
45
48
  var import_bcryptjs = require("bcryptjs");
46
49
  var import_jsonwebtoken = require("jsonwebtoken");
@@ -258,7 +261,9 @@ var getDeleteRoute = (options) => async (req) => {
258
261
  // src/auth/email/routes/get.ts
259
262
  var getGetRoute = (options) => async (req) => {
260
263
  const refresh = req.cookies.get(REFRESH_COOKIE_NAME)?.value;
261
- const userID = getUserIdFromRefreshToken(refresh);
264
+ const requestBody = refresh ? null : await req.json();
265
+ const bodyRefresh = requestBody?.[REFRESH_COOKIE_NAME];
266
+ const userID = getUserIdFromRefreshToken(refresh || bodyRefresh);
262
267
  if (userID) {
263
268
  if (options.onRefresh) {
264
269
  const body = await req.json();
@@ -382,18 +387,58 @@ function AuthFetch() {
382
387
  }
383
388
 
384
389
  // src/auth/email/index.ts
390
+ function getCorsHeaders(origin, allowedOrigins) {
391
+ if (!origin || !allowedOrigins.includes(origin)) return null;
392
+ return {
393
+ "Access-Control-Allow-Origin": origin,
394
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
395
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
396
+ "Access-Control-Allow-Credentials": "true"
397
+ };
398
+ }
399
+ function withCors(handler, allowedOrigins) {
400
+ if (!allowedOrigins?.length) return handler;
401
+ return ((req) => {
402
+ return handler(req).then((response) => {
403
+ if (!response) return response;
404
+ const corsHeaders = getCorsHeaders(
405
+ req.headers.get("origin"),
406
+ allowedOrigins
407
+ );
408
+ if (corsHeaders) {
409
+ Object.entries(corsHeaders).forEach(([key, value]) => {
410
+ response.headers.set(key, value);
411
+ });
412
+ }
413
+ return response;
414
+ });
415
+ });
416
+ }
385
417
  function getEmailAuthRoutes(options) {
418
+ const { allowedOrigins } = options;
386
419
  return {
387
- GET: getGetRoute(options),
388
- POST: getPostRoute(options),
389
- PUT: getPutRoute(options),
390
- DELETE: getDeleteRoute(options)
420
+ GET: withCors(getGetRoute(options), allowedOrigins),
421
+ POST: withCors(getPostRoute(options), allowedOrigins),
422
+ PUT: withCors(getPutRoute(options), allowedOrigins),
423
+ DELETE: withCors(getDeleteRoute(options), allowedOrigins),
424
+ ...allowedOrigins?.length ? {
425
+ OPTIONS: (req) => {
426
+ const corsHeaders = getCorsHeaders(
427
+ req.headers.get("origin"),
428
+ allowedOrigins
429
+ );
430
+ return new import_server4.NextResponse(null, {
431
+ status: 204,
432
+ headers: corsHeaders ?? void 0
433
+ });
434
+ }
435
+ } : {}
391
436
  };
392
437
  }
393
438
 
394
439
  // src/auth/google/get.ts
395
440
  var import_googleapis = require("googleapis");
396
- var import_server5 = require("next/server");
441
+ var import_server6 = require("next/server");
397
442
  var import_uuid = require("uuid");
398
443
  var getGoogleGetRoute = ({
399
444
  getUserIdFromEmail,
@@ -423,7 +468,7 @@ var getGoogleGetRoute = ({
423
468
  prompt: "consent",
424
469
  redirect_uri: url
425
470
  });
426
- const res = import_server5.NextResponse.redirect(authorizationUrl);
471
+ const res = import_server6.NextResponse.redirect(authorizationUrl);
427
472
  res.cookies.set("state", state2, {
428
473
  httpOnly: true,
429
474
  secure: true
@@ -432,12 +477,12 @@ var getGoogleGetRoute = ({
432
477
  }
433
478
  const errorURL = errorRedirectURL || redirectURL;
434
479
  if (error) {
435
- return import_server5.NextResponse.redirect(errorURL);
480
+ return import_server6.NextResponse.redirect(errorURL);
436
481
  }
437
482
  const state = req.nextUrl.searchParams.get("state") || void 0;
438
483
  if (code && state) {
439
484
  const localState = req.cookies.get("state")?.value;
440
- if (localState !== state) return import_server5.NextResponse.redirect(errorURL);
485
+ if (localState !== state) return import_server6.NextResponse.redirect(errorURL);
441
486
  const { tokens } = await oauth2Client.getToken(code);
442
487
  oauth2Client.setCredentials(tokens);
443
488
  const userInfoRequest = await import_googleapis.google.oauth2({
@@ -449,7 +494,7 @@ var getGoogleGetRoute = ({
449
494
  const { data } = JSON.parse(localState);
450
495
  const id = await getUserIdFromEmail(user, data);
451
496
  if (id) {
452
- const res = import_server5.NextResponse.redirect(redirectURL);
497
+ const res = import_server6.NextResponse.redirect(redirectURL);
453
498
  res.cookies.set(
454
499
  REFRESH_COOKIE_NAME,
455
500
  generateRefreshToken(id, getEnv("REFRESH_KEY" /* REFRESH_KEY */)),
@@ -467,7 +512,7 @@ var getGoogleGetRoute = ({
467
512
  }
468
513
  }
469
514
  }
470
- return import_server5.NextResponse.redirect(errorURL);
515
+ return import_server6.NextResponse.redirect(errorURL);
471
516
  };
472
517
  };
473
518
 
@@ -479,7 +524,7 @@ function initGoogleAuth(props) {
479
524
  }
480
525
 
481
526
  // src/auth/instagram/route.ts
482
- var import_server7 = require("next/server");
527
+ var import_server8 = require("next/server");
483
528
 
484
529
  // src/auth/instagram/utils.ts
485
530
  async function getRefreshedInstagramAccessToken(token) {
@@ -541,7 +586,7 @@ var getInstagramUser = (token, id, fields) => {
541
586
  };
542
587
 
543
588
  // src/socials/meta-webhook.ts
544
- var import_server6 = require("next/server");
589
+ var import_server7 = require("next/server");
545
590
 
546
591
  // src/auth/instagram/route.ts
547
592
  var getInstagramRoute = ({
@@ -549,7 +594,7 @@ var getInstagramRoute = ({
549
594
  errorRedirectURL,
550
595
  onUser
551
596
  }) => {
552
- const handleError2 = (message) => import_server7.NextResponse.redirect(`${errorRedirectURL}?error=${message}`);
597
+ const handleError2 = (message) => import_server8.NextResponse.redirect(`${errorRedirectURL}?error=${message}`);
553
598
  return async (req) => {
554
599
  const accessCode = req.nextUrl.searchParams.get("code");
555
600
  const error = req.nextUrl.searchParams.get("error");
@@ -573,7 +618,7 @@ var getInstagramRoute = ({
573
618
  instagramData.accessToken
574
619
  );
575
620
  if (errorMessage) return handleError2(errorMessage);
576
- return import_server7.NextResponse.redirect(redirectURL);
621
+ return import_server8.NextResponse.redirect(redirectURL);
577
622
  };
578
623
  };
579
624
 
@@ -1,3 +1,6 @@
1
+ // src/auth/email/index.ts
2
+ import { NextResponse as NextResponse3 } from "next/server";
3
+
1
4
  // src/auth/email/token.ts
2
5
  import { compare } from "bcryptjs";
3
6
  import { JsonWebTokenError, sign, verify } from "jsonwebtoken";
@@ -215,7 +218,9 @@ var getDeleteRoute = (options) => async (req) => {
215
218
  // src/auth/email/routes/get.ts
216
219
  var getGetRoute = (options) => async (req) => {
217
220
  const refresh = req.cookies.get(REFRESH_COOKIE_NAME)?.value;
218
- const userID = getUserIdFromRefreshToken(refresh);
221
+ const requestBody = refresh ? null : await req.json();
222
+ const bodyRefresh = requestBody?.[REFRESH_COOKIE_NAME];
223
+ const userID = getUserIdFromRefreshToken(refresh || bodyRefresh);
219
224
  if (userID) {
220
225
  if (options.onRefresh) {
221
226
  const body = await req.json();
@@ -343,18 +348,58 @@ function AuthFetch() {
343
348
  }
344
349
 
345
350
  // src/auth/email/index.ts
351
+ function getCorsHeaders(origin, allowedOrigins) {
352
+ if (!origin || !allowedOrigins.includes(origin)) return null;
353
+ return {
354
+ "Access-Control-Allow-Origin": origin,
355
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
356
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
357
+ "Access-Control-Allow-Credentials": "true"
358
+ };
359
+ }
360
+ function withCors(handler, allowedOrigins) {
361
+ if (!allowedOrigins?.length) return handler;
362
+ return ((req) => {
363
+ return handler(req).then((response) => {
364
+ if (!response) return response;
365
+ const corsHeaders = getCorsHeaders(
366
+ req.headers.get("origin"),
367
+ allowedOrigins
368
+ );
369
+ if (corsHeaders) {
370
+ Object.entries(corsHeaders).forEach(([key, value]) => {
371
+ response.headers.set(key, value);
372
+ });
373
+ }
374
+ return response;
375
+ });
376
+ });
377
+ }
346
378
  function getEmailAuthRoutes(options) {
379
+ const { allowedOrigins } = options;
347
380
  return {
348
- GET: getGetRoute(options),
349
- POST: getPostRoute(options),
350
- PUT: getPutRoute(options),
351
- DELETE: getDeleteRoute(options)
381
+ GET: withCors(getGetRoute(options), allowedOrigins),
382
+ POST: withCors(getPostRoute(options), allowedOrigins),
383
+ PUT: withCors(getPutRoute(options), allowedOrigins),
384
+ DELETE: withCors(getDeleteRoute(options), allowedOrigins),
385
+ ...allowedOrigins?.length ? {
386
+ OPTIONS: (req) => {
387
+ const corsHeaders = getCorsHeaders(
388
+ req.headers.get("origin"),
389
+ allowedOrigins
390
+ );
391
+ return new NextResponse3(null, {
392
+ status: 204,
393
+ headers: corsHeaders ?? void 0
394
+ });
395
+ }
396
+ } : {}
352
397
  };
353
398
  }
354
399
 
355
400
  // src/auth/google/get.ts
356
401
  import { google } from "googleapis";
357
- import { NextResponse as NextResponse3 } from "next/server";
402
+ import { NextResponse as NextResponse4 } from "next/server";
358
403
  import { v4 } from "uuid";
359
404
  var getGoogleGetRoute = ({
360
405
  getUserIdFromEmail,
@@ -384,7 +429,7 @@ var getGoogleGetRoute = ({
384
429
  prompt: "consent",
385
430
  redirect_uri: url
386
431
  });
387
- const res = NextResponse3.redirect(authorizationUrl);
432
+ const res = NextResponse4.redirect(authorizationUrl);
388
433
  res.cookies.set("state", state2, {
389
434
  httpOnly: true,
390
435
  secure: true
@@ -393,12 +438,12 @@ var getGoogleGetRoute = ({
393
438
  }
394
439
  const errorURL = errorRedirectURL || redirectURL;
395
440
  if (error) {
396
- return NextResponse3.redirect(errorURL);
441
+ return NextResponse4.redirect(errorURL);
397
442
  }
398
443
  const state = req.nextUrl.searchParams.get("state") || void 0;
399
444
  if (code && state) {
400
445
  const localState = req.cookies.get("state")?.value;
401
- if (localState !== state) return NextResponse3.redirect(errorURL);
446
+ if (localState !== state) return NextResponse4.redirect(errorURL);
402
447
  const { tokens } = await oauth2Client.getToken(code);
403
448
  oauth2Client.setCredentials(tokens);
404
449
  const userInfoRequest = await google.oauth2({
@@ -410,7 +455,7 @@ var getGoogleGetRoute = ({
410
455
  const { data } = JSON.parse(localState);
411
456
  const id = await getUserIdFromEmail(user, data);
412
457
  if (id) {
413
- const res = NextResponse3.redirect(redirectURL);
458
+ const res = NextResponse4.redirect(redirectURL);
414
459
  res.cookies.set(
415
460
  REFRESH_COOKIE_NAME,
416
461
  generateRefreshToken(id, getEnv("REFRESH_KEY" /* REFRESH_KEY */)),
@@ -428,7 +473,7 @@ var getGoogleGetRoute = ({
428
473
  }
429
474
  }
430
475
  }
431
- return NextResponse3.redirect(errorURL);
476
+ return NextResponse4.redirect(errorURL);
432
477
  };
433
478
  };
434
479
 
@@ -440,7 +485,7 @@ function initGoogleAuth(props) {
440
485
  }
441
486
 
442
487
  // src/auth/instagram/route.ts
443
- import { NextResponse as NextResponse5 } from "next/server";
488
+ import { NextResponse as NextResponse6 } from "next/server";
444
489
 
445
490
  // src/auth/instagram/utils.ts
446
491
  async function getRefreshedInstagramAccessToken(token) {
@@ -502,7 +547,7 @@ var getInstagramUser = (token, id, fields) => {
502
547
  };
503
548
 
504
549
  // src/socials/meta-webhook.ts
505
- import { NextResponse as NextResponse4 } from "next/server";
550
+ import { NextResponse as NextResponse5 } from "next/server";
506
551
 
507
552
  // src/auth/instagram/route.ts
508
553
  var getInstagramRoute = ({
@@ -510,7 +555,7 @@ var getInstagramRoute = ({
510
555
  errorRedirectURL,
511
556
  onUser
512
557
  }) => {
513
- const handleError2 = (message) => NextResponse5.redirect(`${errorRedirectURL}?error=${message}`);
558
+ const handleError2 = (message) => NextResponse6.redirect(`${errorRedirectURL}?error=${message}`);
514
559
  return async (req) => {
515
560
  const accessCode = req.nextUrl.searchParams.get("code");
516
561
  const error = req.nextUrl.searchParams.get("error");
@@ -534,7 +579,7 @@ var getInstagramRoute = ({
534
579
  instagramData.accessToken
535
580
  );
536
581
  if (errorMessage) return handleError2(errorMessage);
537
- return NextResponse5.redirect(redirectURL);
582
+ return NextResponse6.redirect(redirectURL);
538
583
  };
539
584
  };
540
585
 
@@ -32,6 +32,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  var client_exports = {};
33
33
  __export(client_exports, {
34
34
  ApolloWrapper: () => ApolloWrapper,
35
+ ApolloWrapperNext: () => ApolloWrapperNext,
35
36
  tokenContext: () => tokenContext,
36
37
  useAuthMutation: () => useAuthMutation,
37
38
  useAuthQuery: () => useAuthQuery
@@ -92,19 +93,33 @@ function getEnv(key, skipCheck) {
92
93
  }
93
94
 
94
95
  // src/graphql/client.tsx
96
+ function makeClient(cacheConfig) {
97
+ return new import_client_integration_nextjs.ApolloClient({
98
+ cache: new import_client_integration_nextjs.InMemoryCache(cacheConfig),
99
+ link: new import_client.HttpLink({
100
+ uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
101
+ })
102
+ });
103
+ }
104
+ var ApolloWrapperNext = ({
105
+ children,
106
+ cacheConfig
107
+ }) => {
108
+ return /* @__PURE__ */ import_react.default.createElement(import_client_integration_nextjs.ApolloNextAppProvider, { makeClient: () => makeClient(cacheConfig) }, children);
109
+ };
110
+ function makeClientBasic(cacheConfig) {
111
+ return new import_client.ApolloClient({
112
+ cache: new import_client.InMemoryCache(cacheConfig),
113
+ link: new import_client.HttpLink({
114
+ uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
115
+ })
116
+ });
117
+ }
95
118
  var ApolloWrapper = ({
96
119
  children,
97
120
  cacheConfig
98
121
  }) => {
99
- function makeClient() {
100
- return new import_client_integration_nextjs.ApolloClient({
101
- cache: new import_client_integration_nextjs.InMemoryCache(cacheConfig),
102
- link: new import_client.HttpLink({
103
- uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
104
- })
105
- });
106
- }
107
- return /* @__PURE__ */ import_react.default.createElement(import_client_integration_nextjs.ApolloNextAppProvider, { makeClient }, children);
122
+ return /* @__PURE__ */ import_react.default.createElement(import_client.ApolloProvider, { client: makeClientBasic(cacheConfig) }, children);
108
123
  };
109
124
  var tokenContext = (token) => {
110
125
  if (!token) return void 0;
@@ -157,6 +172,7 @@ function useAuthMutation(mutation, options) {
157
172
  // Annotate the CommonJS export names for ESM import in node:
158
173
  0 && (module.exports = {
159
174
  ApolloWrapper,
175
+ ApolloWrapperNext,
160
176
  tokenContext,
161
177
  useAuthMutation,
162
178
  useAuthQuery
@@ -3,38 +3,9 @@ import { InMemoryCacheConfig, OperationVariables, MutationHookOptions } from '@a
3
3
  import { TypedDocumentNode } from '@graphql-typed-document-node/core';
4
4
  import React__default, { PropsWithChildren } from 'react';
5
5
 
6
- /**
7
- * Apollo Client provider for Next.js. Wrap your app (or a subtree) so client components can run GraphQL queries and mutations.
8
- * The GraphQL endpoint is read from `NEXT_PUBLIC_GRAPHQL_ENDPOINT` env var.
9
- *
10
- * Must be placed **inside** `AuthWrapper` (since `useAuthQuery` / `useAuthMutation` depend on the auth token).
11
- *
12
- * @param props - Component props.
13
- * @param props.children - React children (your app or page content).
14
- * @param props.cacheConfig - Optional `InMemoryCache` config (e.g. `typePolicies`, `addTypename`). Passed to Apollo's `InMemoryCache`.
15
- * @returns Provider component that supplies Apollo Client to the tree.
16
- *
17
- * @example
18
- * ```tsx
19
- * // app/layout.tsx
20
- * import { AuthWrapper } from "naystack/auth/email/client";
21
- * import { ApolloWrapper } from "naystack/graphql/client";
22
- *
23
- * export default function RootLayout({ children }: { children: React.ReactNode }) {
24
- * return (
25
- * <html lang="en">
26
- * <body>
27
- * <AuthWrapper>
28
- * <ApolloWrapper>{children}</ApolloWrapper>
29
- * </AuthWrapper>
30
- * </body>
31
- * </html>
32
- * );
33
- * }
34
- * ```
35
- *
36
- * @category GraphQL
37
- */
6
+ declare const ApolloWrapperNext: ({ children, cacheConfig, }: PropsWithChildren<{
7
+ cacheConfig?: InMemoryCacheConfig;
8
+ }>) => React__default.JSX.Element;
38
9
  declare const ApolloWrapper: ({ children, cacheConfig, }: PropsWithChildren<{
39
10
  cacheConfig?: InMemoryCacheConfig;
40
11
  }>) => React__default.JSX.Element;
@@ -128,4 +99,4 @@ declare function useAuthQuery<T, V extends OperationVariables>(query: TypedDocum
128
99
  */
129
100
  declare function useAuthMutation<T, V extends OperationVariables>(mutation: TypedDocumentNode<T, V>, options?: MutationHookOptions<T, V>): readonly [(input?: V["input"]) => Promise<_apollo_client.FetchResult<T>>, _apollo_client.MutationResult<T>];
130
101
 
131
- export { ApolloWrapper, tokenContext, useAuthMutation, useAuthQuery };
102
+ export { ApolloWrapper, ApolloWrapperNext, tokenContext, useAuthMutation, useAuthQuery };
@@ -3,38 +3,9 @@ import { InMemoryCacheConfig, OperationVariables, MutationHookOptions } from '@a
3
3
  import { TypedDocumentNode } from '@graphql-typed-document-node/core';
4
4
  import React__default, { PropsWithChildren } from 'react';
5
5
 
6
- /**
7
- * Apollo Client provider for Next.js. Wrap your app (or a subtree) so client components can run GraphQL queries and mutations.
8
- * The GraphQL endpoint is read from `NEXT_PUBLIC_GRAPHQL_ENDPOINT` env var.
9
- *
10
- * Must be placed **inside** `AuthWrapper` (since `useAuthQuery` / `useAuthMutation` depend on the auth token).
11
- *
12
- * @param props - Component props.
13
- * @param props.children - React children (your app or page content).
14
- * @param props.cacheConfig - Optional `InMemoryCache` config (e.g. `typePolicies`, `addTypename`). Passed to Apollo's `InMemoryCache`.
15
- * @returns Provider component that supplies Apollo Client to the tree.
16
- *
17
- * @example
18
- * ```tsx
19
- * // app/layout.tsx
20
- * import { AuthWrapper } from "naystack/auth/email/client";
21
- * import { ApolloWrapper } from "naystack/graphql/client";
22
- *
23
- * export default function RootLayout({ children }: { children: React.ReactNode }) {
24
- * return (
25
- * <html lang="en">
26
- * <body>
27
- * <AuthWrapper>
28
- * <ApolloWrapper>{children}</ApolloWrapper>
29
- * </AuthWrapper>
30
- * </body>
31
- * </html>
32
- * );
33
- * }
34
- * ```
35
- *
36
- * @category GraphQL
37
- */
6
+ declare const ApolloWrapperNext: ({ children, cacheConfig, }: PropsWithChildren<{
7
+ cacheConfig?: InMemoryCacheConfig;
8
+ }>) => React__default.JSX.Element;
38
9
  declare const ApolloWrapper: ({ children, cacheConfig, }: PropsWithChildren<{
39
10
  cacheConfig?: InMemoryCacheConfig;
40
11
  }>) => React__default.JSX.Element;
@@ -128,4 +99,4 @@ declare function useAuthQuery<T, V extends OperationVariables>(query: TypedDocum
128
99
  */
129
100
  declare function useAuthMutation<T, V extends OperationVariables>(mutation: TypedDocumentNode<T, V>, options?: MutationHookOptions<T, V>): readonly [(input?: V["input"]) => Promise<_apollo_client.FetchResult<T>>, _apollo_client.MutationResult<T>];
130
101
 
131
- export { ApolloWrapper, tokenContext, useAuthMutation, useAuthQuery };
102
+ export { ApolloWrapper, ApolloWrapperNext, tokenContext, useAuthMutation, useAuthQuery };
@@ -2,7 +2,10 @@
2
2
 
3
3
  // src/graphql/client.tsx
4
4
  import {
5
+ ApolloClient as ApolloClientBasic,
6
+ ApolloProvider,
5
7
  HttpLink,
8
+ InMemoryCache as InMemoryCacheBasic,
6
9
  useLazyQuery,
7
10
  useMutation
8
11
  } from "@apollo/client";
@@ -68,19 +71,33 @@ function getEnv(key, skipCheck) {
68
71
  }
69
72
 
70
73
  // src/graphql/client.tsx
74
+ function makeClient(cacheConfig) {
75
+ return new ApolloClient({
76
+ cache: new InMemoryCache(cacheConfig),
77
+ link: new HttpLink({
78
+ uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
79
+ })
80
+ });
81
+ }
82
+ var ApolloWrapperNext = ({
83
+ children,
84
+ cacheConfig
85
+ }) => {
86
+ return /* @__PURE__ */ React.createElement(ApolloNextAppProvider, { makeClient: () => makeClient(cacheConfig) }, children);
87
+ };
88
+ function makeClientBasic(cacheConfig) {
89
+ return new ApolloClientBasic({
90
+ cache: new InMemoryCacheBasic(cacheConfig),
91
+ link: new HttpLink({
92
+ uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
93
+ })
94
+ });
95
+ }
71
96
  var ApolloWrapper = ({
72
97
  children,
73
98
  cacheConfig
74
99
  }) => {
75
- function makeClient() {
76
- return new ApolloClient({
77
- cache: new InMemoryCache(cacheConfig),
78
- link: new HttpLink({
79
- uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
80
- })
81
- });
82
- }
83
- return /* @__PURE__ */ React.createElement(ApolloNextAppProvider, { makeClient }, children);
100
+ return /* @__PURE__ */ React.createElement(ApolloProvider, { client: makeClientBasic(cacheConfig) }, children);
84
101
  };
85
102
  var tokenContext = (token) => {
86
103
  if (!token) return void 0;
@@ -132,6 +149,7 @@ function useAuthMutation(mutation, options) {
132
149
  }
133
150
  export {
134
151
  ApolloWrapper,
152
+ ApolloWrapperNext,
135
153
  tokenContext,
136
154
  useAuthMutation,
137
155
  useAuthQuery
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naystack",
3
- "version": "1.5.25",
3
+ "version": "1.5.27",
4
4
  "description": "A stack built with Next + GraphQL + S3 + Auth",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",