Skip to content

Commit

Permalink
Add /session-sync for restoring sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
bookernath committed Dec 22, 2024
1 parent 3aba343 commit f4c7514
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/gold-singers-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-core": patch
---

Support session sync endpoint
87 changes: 87 additions & 0 deletions core/app/session-sync/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { unstable_rethrow as rethrow, redirect } from 'next/navigation';
import { graphql } from '~/client/graphql';
import { client } from '~/client';
import { signIn } from '~/auth';
import { setCartId } from '~/lib/cookies/cart';

// GQL mutation for validating Session Sync JWT
const ValidateSessionSyncJwt = graphql(`
mutation ValidateSessionSyncJwt($jwt: String!) {
validateSessionSyncJwt(jwt: $jwt) {
errors {
... on InvalidSessionSyncJwtError {
errorType
message
}
... on JwtTokenExpiredError {
message
}
}
content {
cart {
entityId
}
customer {
entityId
firstName
lastName
email
}
customerAccessToken {
value
}
redirectTo
}
}
}
`);

export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const jwt = searchParams.get('jwt');

if (!jwt) {
return redirect('/login?error=MissingToken');
}

try {
// Validate the session sync JWT
const response = await client.fetch({
document: ValidateSessionSyncJwt,
variables: { jwt },
fetchOptions: { cache: 'no-store' },
});

const data = response.data.validateSessionSyncJwt;
if (data.errors?.length) {
return redirect('/login?error=InvalidToken');
}

// Restore cart
if (data.content?.cart?.entityId) {
await setCartId(data.content.cart.entityId);
}

// Restore the customer session
// (signIn will re-validate an active session for next-auth)
if (data.content?.customerAccessToken?.value) {
await signIn('credentials', {
type: 'jwt',
jwt: data.content.customerAccessToken.value,
redirectTo: data.content.redirectTo,
});
}

// Get relative redirectTo path from full URL
const redirectTo = new URL(data.content?.redirectTo || '/').pathname;

// Finally, redirect user to the redirectTo parameter or default page
redirect(redirectTo);
} catch (error) {
rethrow(error);
redirect('/login?error=InvalidToken');
}
}

export const runtime = 'edge';
export const dynamic = 'force-dynamic';
6 changes: 4 additions & 2 deletions core/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ export const config = {
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - _vercel (vercel internals, eg: web vitals)
* - _vercel (vercel internals)
* - favicon.ico (favicon file)
* - admin (admin panel)
* - sitemap.xml (sitemap route)
* - xmlsitemap.php (legacy sitemap route)
* - robots.txt (robots route)
* - login/token
* - session-sync
*/
'/((?!api|admin|_next/static|_next/image|_vercel|favicon.ico|xmlsitemap.php|sitemap.xml|robots.txt|login/token).*)',
'/((?!api|admin|_next/static|_next/image|_vercel|favicon.ico|xmlsitemap.php|sitemap.xml|robots.txt|login/token|session-sync).*)',
],
};

0 comments on commit f4c7514

Please sign in to comment.