@opexa/portal-components 0.0.176 → 0.0.177

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.
@@ -0,0 +1,3 @@
1
+ import type { Mutation } from '../../types';
2
+ import { type UpdateSessionInput } from '../services/updateSession';
3
+ export declare const useUpdateSessionMutation: Mutation<boolean, UpdateSessionInput>;
@@ -0,0 +1,26 @@
1
+ import { useMutation } from '@tanstack/react-query';
2
+ import { getQueryClient } from '../../utils/getQueryClient.js';
3
+ import { getUpdateSessionMutationKey } from '../../utils/mutationKeys.js';
4
+ import { getSessionQueryKey } from '../../utils/queryKeys.js';
5
+ import { updateSession, } from '../services/updateSession.js';
6
+ export const useUpdateSessionMutation = (config) => {
7
+ const queryClient = getQueryClient();
8
+ return useMutation({
9
+ ...config,
10
+ mutationKey: getUpdateSessionMutationKey(),
11
+ mutationFn: async (input) => {
12
+ const ok = await updateSession(input);
13
+ queryClient.setQueryData(getSessionQueryKey(), (prev) => {
14
+ if (!prev)
15
+ return prev;
16
+ if (!input.domain)
17
+ return prev;
18
+ return {
19
+ ...prev,
20
+ ...input,
21
+ };
22
+ });
23
+ return ok;
24
+ },
25
+ });
26
+ };
@@ -0,0 +1,5 @@
1
+ import { type HttpRequestOptions } from '../../services/httpRequest';
2
+ export interface UpdateSessionInput {
3
+ domain?: string;
4
+ }
5
+ export declare const updateSession: (input: UpdateSessionInput, options?: HttpRequestOptions) => Promise<boolean>;
@@ -0,0 +1,10 @@
1
+ import { cache } from 'react';
2
+ import { httpRequest, } from '../../services/httpRequest.js';
3
+ export const updateSession = cache(async (input, options) => {
4
+ const { ok } = await httpRequest.json('/api/sessions', {
5
+ ...options,
6
+ method: 'PATCH',
7
+ body: JSON.stringify(input),
8
+ });
9
+ return ok;
10
+ });
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import { type ReactNode } from 'react';
2
2
  export interface PortalProviderProps {
3
3
  googleAnalyticsId?: string;
4
4
  googleTagManagerId?: string;
@@ -1,6 +1,7 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { GoogleAnalytics, GoogleTagManager } from '@next/third-parties/google';
3
3
  import { dehydrate, HydrationBoundary } from '@tanstack/react-query';
4
+ import { Suspense } from 'react';
4
5
  import { prefetchAccountQuery } from '../../server/utils/prefetchAccountQuery.js';
5
6
  import { prefetchPlatformQuery } from '../../server/utils/prefetchPlatformQuery.js';
6
7
  import { prefetchSessionQuery } from '../../server/utils/prefetchSessionQuery.js';
@@ -8,6 +9,7 @@ import { prefetchWalletQuery } from '../../server/utils/prefetchWalletQuery.js';
8
9
  import { FacebookPixel, GoogleRecaptcha } from '../../third-parties/index.js';
9
10
  import { getQueryClient } from '../../utils/getQueryClient.js';
10
11
  import { Providers } from './Providers.js';
12
+ import { SetupDomain } from './SetupDomain.js';
11
13
  import { Snackbar } from './Snackbar.js';
12
14
  import { WebVitals } from './WebVitals.js';
13
15
  export async function PortalProvider({ children, facebookPixelId, googleAnalyticsId, googleTagManagerId, googleRecaptchaSiteKey, }) {
@@ -18,5 +20,5 @@ export async function PortalProvider({ children, facebookPixelId, googleAnalytic
18
20
  prefetchAccountQuery(),
19
21
  prefetchWalletQuery(),
20
22
  ]);
21
- return (_jsxs(_Fragment, { children: [_jsx(WebVitals, {}), _jsx(Providers, { children: _jsx(HydrationBoundary, { state: dehydrate(queryClient), children: children }) }), _jsx(Snackbar, {}), facebookPixelId && _jsx(FacebookPixel, { fbId: facebookPixelId }), googleAnalyticsId && _jsx(GoogleAnalytics, { gaId: googleAnalyticsId }), googleTagManagerId && _jsx(GoogleTagManager, { gtmId: googleTagManagerId }), googleRecaptchaSiteKey && (_jsx(GoogleRecaptcha, { siteKey: googleRecaptchaSiteKey }))] }));
23
+ return (_jsxs(_Fragment, { children: [_jsx(WebVitals, {}), _jsx(Providers, { children: _jsxs(HydrationBoundary, { state: dehydrate(queryClient), children: [children, _jsx(Suspense, { fallback: null, children: _jsx(SetupDomain, {}) })] }) }), _jsx(Snackbar, {}), facebookPixelId && _jsx(FacebookPixel, { fbId: facebookPixelId }), googleAnalyticsId && _jsx(GoogleAnalytics, { gaId: googleAnalyticsId }), googleTagManagerId && _jsx(GoogleTagManager, { gtmId: googleTagManagerId }), googleRecaptchaSiteKey && (_jsx(GoogleRecaptcha, { siteKey: googleRecaptchaSiteKey }))] }));
22
24
  }
@@ -0,0 +1 @@
1
+ export declare function SetupDomain(): null;
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { useSearchParams } from 'next/navigation';
3
+ import { useTimeout } from 'usehooks-ts';
4
+ import { useSessionQuery } from '../../client/hooks/useSessionQuery.js';
5
+ import { useUpdateSessionMutation } from '../../client/hooks/useUpdateSessionMutation.js';
6
+ export function SetupDomain() {
7
+ const searchParams = useSearchParams();
8
+ const sessionQuery = useSessionQuery();
9
+ const updateSessionMutation = useUpdateSessionMutation();
10
+ useTimeout(() => {
11
+ const market = searchParams.get('m');
12
+ const domain = `${window.location.host}/${market}`;
13
+ if (domain === sessionQuery.data?.domain)
14
+ return;
15
+ updateSessionMutation.mutate({ domain });
16
+ }, sessionQuery.isPending ? null : searchParams.has('m') ? 1000 : null);
17
+ return null;
18
+ }
@@ -36,3 +36,8 @@ export declare const POST: (request: NextRequest, { params }: {
36
36
  auth: string[];
37
37
  }>;
38
38
  }) => Promise<NextResponse>;
39
+ export declare const PATCH: (request: NextRequest, { params }: {
40
+ params: Promise<{
41
+ auth: string[];
42
+ }>;
43
+ }) => Promise<NextResponse>;
package/dist/handlers.js CHANGED
@@ -62,7 +62,7 @@ export const GET = async (request, { params }) => {
62
62
  if (path === 'sessions') {
63
63
  const accessToken = request.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value;
64
64
  const refreshToken = request.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value;
65
- const domain = request.cookies.get(DOMAIN_COOKIE_NAME)?.value ?? request.nextUrl.origin;
65
+ const domain = request.cookies.get(DOMAIN_COOKIE_NAME)?.value ?? request.nextUrl.host;
66
66
  if (!refreshToken) {
67
67
  const response = NextResponse.json({
68
68
  ok: true,
@@ -260,3 +260,38 @@ export const POST = async (request, { params }) => {
260
260
  message: 'Not found',
261
261
  }, { status: 404 });
262
262
  };
263
+ const UpdateSessionDefinition = z.object({
264
+ domain: z.string().optional().nullable(),
265
+ });
266
+ export const PATCH = async (request, { params }) => {
267
+ const { auth } = await params;
268
+ const path = auth[0];
269
+ /*
270
+ *
271
+ * PATCH -> /api/sessions
272
+ *
273
+ */
274
+ if (path === 'sessions') {
275
+ const body = await request.json();
276
+ const parsed = UpdateSessionDefinition.safeParse(body);
277
+ if (!parsed.success) {
278
+ return NextResponse.json({
279
+ ok: false,
280
+ message: parsed.error.issues[0].message,
281
+ }, { status: 400 });
282
+ }
283
+ const response = NextResponse.json({ ok: true });
284
+ if (parsed.data.domain) {
285
+ response.cookies.set(DOMAIN_COOKIE_NAME, parsed.data.domain, {
286
+ expires: addDays(new Date(), 30),
287
+ httpOnly: true,
288
+ sameSite: 'strict',
289
+ });
290
+ }
291
+ return response;
292
+ }
293
+ return NextResponse.json({
294
+ ok: false,
295
+ message: 'Not found',
296
+ }, { status: 404 });
297
+ };
@@ -1,25 +1,11 @@
1
- import { addDays, addMinutes } from 'date-fns';
1
+ import { addMinutes } from 'date-fns';
2
2
  import { NextFetchEvent, NextResponse, } from 'next/server';
3
- import { ACCESS_TOKEN_COOKIE_NAME, DOMAIN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME, } from './constants/index.js';
3
+ import { ACCESS_TOKEN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME, } from './constants/index.js';
4
4
  import { refreshSession } from './services/auth.js';
5
5
  export const middleware = async (req) => {
6
6
  const accessToken = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value;
7
7
  const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value;
8
8
  const res = NextResponse.next();
9
- if (req.nextUrl.searchParams.has('m')) {
10
- res.cookies.set(DOMAIN_COOKIE_NAME, `${req.nextUrl.hostname}/${req.nextUrl.searchParams.get('m')}`, {
11
- expires: addDays(new Date(), 30),
12
- httpOnly: true,
13
- sameSite: 'strict',
14
- });
15
- }
16
- if (!res.cookies.has(DOMAIN_COOKIE_NAME)) {
17
- res.cookies.set(DOMAIN_COOKIE_NAME, req.nextUrl.origin, {
18
- expires: addDays(new Date(), 30),
19
- httpOnly: true,
20
- sameSite: 'strict',
21
- });
22
- }
23
9
  if (!accessToken && refreshToken) {
24
10
  try {
25
11
  const data = await refreshSession({
@@ -5,9 +5,10 @@ export const getSession = cache(async () => {
5
5
  const Cookies = await cookies();
6
6
  const Headers = await headers();
7
7
  const token = Cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value;
8
- const headerProto = Headers.get('x-forwarded-proto') ?? 'http';
9
- const headerHost = Headers.get('x-forwarded-host') ?? 'localhost';
10
- const domain = Cookies.get(DOMAIN_COOKIE_NAME)?.value ?? `${headerProto}://${headerHost}`;
8
+ const domain = Cookies.get(DOMAIN_COOKIE_NAME)?.value ??
9
+ Headers.get('host') ??
10
+ Headers.get('x-forwarded-host') ??
11
+ 'localhost';
11
12
  return token
12
13
  ? {
13
14
  status: 'authenticated',
@@ -30,3 +30,4 @@ export declare const getCompleteOnboardingMutationKey: () => MutationKey;
30
30
  export declare const getSkipOnboardingMutationKey: () => MutationKey;
31
31
  export declare const getUploadImageFileMutationKey: () => MutationKey;
32
32
  export declare const getResetPasswordMutationKey: () => MutationKey;
33
+ export declare const getUpdateSessionMutationKey: () => MutationKey;
@@ -114,3 +114,7 @@ export const getResetPasswordMutationKey = () => [
114
114
  PARENT_KEY,
115
115
  'resetPassword',
116
116
  ];
117
+ export const getUpdateSessionMutationKey = () => [
118
+ PARENT_KEY,
119
+ 'updateSession',
120
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opexa/portal-components",
3
- "version": "0.0.176",
3
+ "version": "0.0.177",
4
4
  "exports": {
5
5
  "./ui/*": {
6
6
  "types": "./dist/ui/*/index.d.ts",