Skip to content

Commit

Permalink
Merge pull request #214 from Shopify/jl-refactor-session
Browse files Browse the repository at this point in the history
Introduce injected `session` util in user-code
  • Loading branch information
jplhomer authored Nov 21, 2022
2 parents 294c6c8 + 356129d commit b934c81
Show file tree
Hide file tree
Showing 21 changed files with 128 additions and 128 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/hydrogen-remix/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export function createRequestHandler(
...options
}: Omit<Parameters<typeof handleRequest>[1], 'loadContext'> &
HydrogenHandlerParams,
customContext?: Record<string, any>,
) => {
try {
if (!cache && !!globalThis.caches) {
Expand All @@ -42,6 +43,7 @@ export function createRequestHandler(
}),
...context,
cache,
...customContext,
},
});

Expand Down
7 changes: 3 additions & 4 deletions templates/demo-store/app/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from '~/lib/utils';
import invariant from 'tiny-invariant';
import {logout} from '~/routes/account/__private/logout';
import type {HydrogenContext} from '@shopify/hydrogen-remix';
import type {AppLoadContext, HydrogenContext} from '@shopify/hydrogen-remix';
import {type Params} from '@remix-run/react';

export interface CountriesData {
Expand Down Expand Up @@ -932,9 +932,8 @@ export async function getCustomerOrder(
}

export async function getCustomer(
context: HydrogenContext,
context: AppLoadContext & HydrogenContext,
{
request,
customerAccessToken,
params,
}: {
Expand All @@ -960,7 +959,7 @@ export async function getCustomer(
* If the customer failed to load, we assume their access token is invalid.
*/
if (!data || !data.customer) {
throw await logout(request, context, params);
throw await logout(context, params);
}

return data.customer;
Expand Down
91 changes: 48 additions & 43 deletions templates/demo-store/app/lib/session.server.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,57 @@
import {
type AppLoadContext,
createCookieSessionStorage,
type SessionStorage,
type Session,
} from '@shopify/hydrogen-remix';

let sessionStorage: SessionStorage;
/**
* This is a custom session implementation for your Hydrogen shop.
* Feel free to customize it to your needs, add helper methods, or
* swap out the cookie-based implementation with something else!
*/
export class HydrogenSession {
constructor(
private sessionStorage: SessionStorage,
private session: Session,
) {}

static async init(request: Request, secrets: string[]) {
const storage = createCookieSessionStorage({
cookie: {
name: 'session',
httpOnly: true,
path: '/',
sameSite: 'lax',
secrets,
},
});

const session = await storage.getSession(request.headers.get('Cookie'));

return new this(storage, session);
}

get(key: string) {
return this.session.get(key);
}

destroy() {
return this.sessionStorage.destroySession(this.session);
}

export async function getSession(
request: Request,
context: AppLoadContext & {env?: Record<string, string>},
) {
if (!context.env?.ENCRYPTION_KEY) {
throw new Error('ENCRYPTION_KEY environment variable is not set');
flash(key: string, value: any) {
this.session.flash(key, value);
}

sessionStorage ??= createCookieSessionStorage({
cookie: {
name: 'session',
httpOnly: true,
path: '/',
sameSite: 'lax',
secrets: [context.env.ENCRYPTION_KEY],
},
});

const session = await sessionStorage.getSession(
request.headers.get('Cookie'),
);

return {
async get(key: string): Promise<any> {
return await session.get(key);
},

set(key: string, value: any): void {
session.set(key, value);
},

flash(key: string, value: any): void {
session.flash(key, value);
},

unset(key: string): void {
session.unset(key);
},

async commit(): Promise<string> {
return await sessionStorage.commitSession(session);
},
};
unset(key: string) {
this.session.unset(key);
}

set(key: string, value: any) {
this.session.set(key, value);
}

commit() {
return this.sessionStorage.commitSession(this.session);
}
}
6 changes: 2 additions & 4 deletions templates/demo-store/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {Layout} from '~/components';
import {getLayoutData, getCountries} from '~/data';
import {GenericError} from './components/GenericError';
import {NotFound} from './components/NotFound';
import {getSession} from './lib/session.server';
import {Seo, Debugger} from './lib/seo';

import styles from './styles/app.css';
Expand Down Expand Up @@ -59,9 +58,8 @@ export const meta: MetaFunction = () => ({
viewport: 'width=device-width,initial-scale=1',
});

export async function loader({request, context, params}: LoaderArgs) {
const session = await getSession(request, context);
const cartId = await session.get('cartId');
export async function loader({context, params}: LoaderArgs) {
const cartId = await context.session.get('cartId');

return defer({
layout: await getLayoutData(context, params),
Expand Down
7 changes: 2 additions & 5 deletions templates/demo-store/app/routes/__resources/cart/LinesAdd.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
} from '@remix-run/react';
import {useIsHydrated} from '~/hooks/useIsHydrated';
import invariant from 'tiny-invariant';
import {getSession} from '~/lib/session.server';
import type {SerializeFrom} from '@remix-run/server-runtime';
import {
type ActionArgs,
Expand Down Expand Up @@ -97,12 +96,10 @@ const ACTION_PATH = '/cart/LinesAdd';
* action that handles cart create (with lines) and lines add
*/
async function action({request, context, params}: ActionArgs) {
const {session} = context;
const headers = new Headers();

const [session, formData] = await Promise.all([
getSession(request, context),
request.formData(),
]);
const formData = await request.formData();

const rawLines = formData.get('lines')
? (JSON.parse(String(formData.get('lines'))) as LinesAddLine[])
Expand Down
4 changes: 1 addition & 3 deletions templates/demo-store/app/routes/account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,12 @@ import {FeaturedCollections} from '~/components/FeaturedCollections';
import {type LoaderArgs, redirect, json, defer} from '@shopify/hydrogen-remix';
import {flattenConnection} from '@shopify/hydrogen-react';
import {getCustomer} from '~/data';
import {getSession} from '~/lib/session.server';
import {getFeaturedData} from './featured-products';

export async function loader({request, context, params}: LoaderArgs) {
const {pathname} = new URL(request.url);
const session = await getSession(request, context);
const lang = params.lang;
const customerAccessToken = await session.get('customerAccessToken');
const customerAccessToken = await context.session.get('customerAccessToken');
const isAuthenticated = Boolean(customerAccessToken);
const loginPath = lang ? `${lang}/account/login` : '/account/login';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
updateCustomerAddress,
updateCustomerDefaultAddress,
} from '~/data';
import {getSession} from '~/lib/session.server';
import {getInputStyleClasses} from '~/lib/utils';
import type {AccountOutletContext} from '../edit';

Expand All @@ -31,12 +30,9 @@ export const handle = {
};

export const action: ActionFunction = async ({request, context, params}) => {
const [formData, session] = await Promise.all([
request.formData(),
getSession(request, context),
]);
const formData = await request.formData();

const customerAccessToken = await session.get('customerAccessToken');
const customerAccessToken = await context.session.get('customerAccessToken');
invariant(customerAccessToken, 'You must be logged in to edit your account.');

const addressId = formData.get('addressId');
Expand Down
8 changes: 2 additions & 6 deletions templates/demo-store/app/routes/account/__private/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import clsx from 'clsx';
import invariant from 'tiny-invariant';
import {Button, Text} from '~/components';
import {getCustomer, updateCustomer} from '~/data';
import {getSession} from '~/lib/session.server';
import {getInputStyleClasses} from '~/lib/utils';

export interface AccountOutletContext {
Expand Down Expand Up @@ -48,12 +47,9 @@ export const handle = {
};

export const action: ActionFunction = async ({request, context, params}) => {
const [formData, session] = await Promise.all([
request.formData(),
getSession(request, context),
]);
const formData = await request.formData();

const customerAccessToken = await session.get('customerAccessToken');
const customerAccessToken = await context.session.get('customerAccessToken');

invariant(
customerAccessToken,
Expand Down
8 changes: 3 additions & 5 deletions templates/demo-store/app/routes/account/__private/logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import {
redirect,
} from '@shopify/hydrogen-remix';
import {LoaderArgs} from '@remix-run/server-runtime';
import {getSession} from '~/lib/session.server';

export async function logout(
request: Request,
context: AppLoadContext,
params: LoaderArgs['params'],
) {
const session = await getSession(request, context);
const {session} = context;
session.unset('customerAccessToken');

return redirect(
Expand All @@ -28,6 +26,6 @@ export async function loader({params}: LoaderArgs) {
return redirect(params.lang ? `${params.lang}/` : '/');
}

export const action: ActionFunction = async ({request, context, params}) => {
return logout(request, context, params);
export const action: ActionFunction = async ({context, params}) => {
return logout(context, params);
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import type {
} from '@shopify/hydrogen-react/storefront-api-types';
import {Link, Heading, PageHeader, Text} from '~/components';
import {getCustomerOrder} from '~/data';
import {getSession} from '~/lib/session.server';

export const meta: MetaFunction = ({data}) => ({
title: `Order ${data?.order?.name}`,
Expand All @@ -32,8 +31,7 @@ export async function loader({request, context, params}: LoaderArgs) {

invariant(orderToken, 'Order token is required');

const session = await getSession(request, context);
const customerAccessToken = await session.get('customerAccessToken');
const customerAccessToken = await context.session.get('customerAccessToken');

if (!customerAccessToken) {
return redirect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
import {Form, useActionData} from '@remix-run/react';
import {useRef, useState} from 'react';
import {activateAccount} from '~/data';
import {getSession} from '~/lib/session.server';
import {getInputStyleClasses} from '~/lib/utils';

type ActionData = {
Expand Down Expand Up @@ -37,10 +36,7 @@ export const action: ActionFunction = async ({
});
}

const [formData, session] = await Promise.all([
request.formData(),
getSession(request, context),
]);
const formData = await request.formData();

const password = formData.get('password');
const passwordConfirm = formData.get('passwordConfirm');
Expand All @@ -64,6 +60,8 @@ export const action: ActionFunction = async ({
password,
});

const {session} = context;

session.set('customerAccessToken', accessToken);

return redirect(lang ? `${lang}/account` : '/account', {
Expand Down
12 changes: 4 additions & 8 deletions templates/demo-store/app/routes/account/__public/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ import {
import {Form, useActionData, useLoaderData} from '@remix-run/react';
import {useState} from 'react';
import {login} from '~/data';
import {getSession} from '~/lib/session.server';
import {getInputStyleClasses} from '~/lib/utils';
import {Link} from '~/components';

export const handle = {
isPublic: true,
};

export async function loader({request, context, params}: LoaderArgs) {
const session = await getSession(request, context);
const customerAccessToken = await session.get('customerAccessToken');
export async function loader({context, params}: LoaderArgs) {
const customerAccessToken = await context.session.get('customerAccessToken');

if (customerAccessToken) {
return redirect(params.lang ? `${params.lang}/account` : '/account');
Expand All @@ -36,10 +34,7 @@ type ActionData = {
const badRequest = (data: ActionData) => json(data, {status: 400});

export const action: ActionFunction = async ({request, context, params}) => {
const [formData, session] = await Promise.all([
request.formData(),
getSession(request, context),
]);
const formData = await request.formData();

const email = formData.get('email');
const password = formData.get('password');
Expand All @@ -57,6 +52,7 @@ export const action: ActionFunction = async ({request, context, params}) => {

try {
const customerAccessToken = await login(context, {email, password});
const {session} = context;
session.set('customerAccessToken', customerAccessToken);

return redirect(params.lang ? `${params.lang}/account` : '/account', {
Expand Down
6 changes: 2 additions & 4 deletions templates/demo-store/app/routes/account/__public/recover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import {
import {Form, useActionData} from '@remix-run/react';
import {useState} from 'react';
import {sendPasswordResetEmail} from '~/data';
import {getSession} from '~/lib/session.server';
import {Link} from '~/components';
import {getInputStyleClasses} from '~/lib/utils';

export async function loader({request, context, params}: LoaderArgs) {
const session = await getSession(request, context);
const customerAccessToken = await session.get('customerAccessToken');
export async function loader({context, params}: LoaderArgs) {
const customerAccessToken = await context.session.get('customerAccessToken');

if (customerAccessToken) {
return redirect(params.lang ? `${params.lang}/account` : '/account');
Expand Down
Loading

0 comments on commit b934c81

Please sign in to comment.