mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36:49 +00:00
auth proccess
This commit is contained in:
8
lib/isAuthenticated.ts
Normal file
8
lib/isAuthenticated.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { NextRequest } from 'next/server';
|
||||
|
||||
const isAuthenticated = (request: NextRequest) => {
|
||||
const customerAccessToken = request.cookies.get('customerAccessToken')?.value;
|
||||
return customerAccessToken;
|
||||
};
|
||||
|
||||
export default isAuthenticated;
|
@@ -4,6 +4,12 @@ import { ensureStartsWith } from 'lib/utils';
|
||||
import { revalidateTag } from 'next/cache';
|
||||
import { headers } from 'next/headers';
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import {
|
||||
CUSTOMER_CREATE_MUTATION,
|
||||
CUSTOMER_RECOVER_MUTATION,
|
||||
CUSTOMER_RESET_MUTATION,
|
||||
LOGIN_MUTATION,
|
||||
} from './mutations/auth';
|
||||
import {
|
||||
addToCartMutation,
|
||||
createCartMutation,
|
||||
@@ -23,10 +29,16 @@ import {
|
||||
getProductRecommendationsQuery,
|
||||
getProductsQuery
|
||||
} from './queries/product';
|
||||
import { CUSTOMER_QUERY } from './queries/user';
|
||||
import {
|
||||
Cart,
|
||||
Collection,
|
||||
Connection,
|
||||
Customer,
|
||||
CustomerAccessTokenCreatePayload,
|
||||
CustomerCreatePayload,
|
||||
CustomerRecoverPayload,
|
||||
CustomerResetPayload,
|
||||
Image,
|
||||
Menu,
|
||||
Page,
|
||||
@@ -47,7 +59,7 @@ import {
|
||||
ShopifyProductRecommendationsOperation,
|
||||
ShopifyProductsOperation,
|
||||
ShopifyRemoveFromCartOperation,
|
||||
ShopifyUpdateCartOperation
|
||||
ShopifyUpdateCartOperation,
|
||||
} from './types';
|
||||
|
||||
const domain = process.env.SHOPIFY_STORE_DOMAIN
|
||||
@@ -282,6 +294,135 @@ export async function getCollection(handle: string): Promise<Collection | undefi
|
||||
return reshapeCollection(res.body.data.collection);
|
||||
}
|
||||
|
||||
export async function createCustomer({
|
||||
variables,
|
||||
}: {
|
||||
variables: {
|
||||
input: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
};
|
||||
}) {
|
||||
const data = await shopifyFetch<{
|
||||
data: {
|
||||
customerCreate: CustomerCreatePayload;
|
||||
};
|
||||
variables: {
|
||||
input: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
};
|
||||
}>({
|
||||
query: CUSTOMER_CREATE_MUTATION,
|
||||
variables,
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function loginCustomer({
|
||||
variables,
|
||||
}: {
|
||||
variables: {
|
||||
input: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
};
|
||||
}) {
|
||||
const data = await shopifyFetch<{
|
||||
data: {
|
||||
customerAccessTokenCreate: CustomerAccessTokenCreatePayload;
|
||||
};
|
||||
variables: {
|
||||
input: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
};
|
||||
}>({
|
||||
query: LOGIN_MUTATION,
|
||||
variables,
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function recoverCustomersPassword({
|
||||
variables,
|
||||
}: {
|
||||
variables: {
|
||||
email: string;
|
||||
};
|
||||
}) {
|
||||
const data = await shopifyFetch<{
|
||||
data: {
|
||||
customerRecover: CustomerRecoverPayload;
|
||||
};
|
||||
variables: {
|
||||
email: string;
|
||||
};
|
||||
}>({
|
||||
query: CUSTOMER_RECOVER_MUTATION,
|
||||
variables,
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function resetCustomersPassword({
|
||||
variables,
|
||||
}: {
|
||||
variables: {
|
||||
id: string;
|
||||
input: {
|
||||
password: string;
|
||||
resetToken: string;
|
||||
};
|
||||
};
|
||||
}) {
|
||||
const data = await shopifyFetch<{
|
||||
data: {
|
||||
customerReset: CustomerResetPayload;
|
||||
};
|
||||
variables: {
|
||||
id: string;
|
||||
input: {
|
||||
password: string;
|
||||
resetToken: string;
|
||||
};
|
||||
};
|
||||
}>({
|
||||
query: CUSTOMER_RESET_MUTATION,
|
||||
variables,
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function getCustomer(
|
||||
customerAccessToken: string
|
||||
): Promise<Customer> {
|
||||
const res = await shopifyFetch<{
|
||||
data: { customer: Customer };
|
||||
variables: {
|
||||
customerAccessToken: string;
|
||||
};
|
||||
}>({
|
||||
query: CUSTOMER_QUERY,
|
||||
variables: {
|
||||
customerAccessToken,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* If the customer failed to load, we assume their access token is invalid.
|
||||
*/
|
||||
if (!res || !res.body.data.customer) {
|
||||
// log out customer
|
||||
}
|
||||
|
||||
return res.body.data.customer;
|
||||
}
|
||||
|
||||
export async function getCollectionProducts({
|
||||
collection,
|
||||
reverse,
|
||||
|
58
lib/shopify/mutations/auth.ts
Normal file
58
lib/shopify/mutations/auth.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
export const CUSTOMER_CREATE_MUTATION = `#graphql
|
||||
mutation customerCreate($input: CustomerCreateInput!) {
|
||||
customerCreate(input: $input) {
|
||||
customer {
|
||||
id
|
||||
}
|
||||
customerUserErrors {
|
||||
code
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const LOGIN_MUTATION = `#graphql
|
||||
mutation customerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) {
|
||||
customerAccessTokenCreate(input: $input) {
|
||||
customerUserErrors {
|
||||
code
|
||||
field
|
||||
message
|
||||
}
|
||||
customerAccessToken {
|
||||
accessToken
|
||||
expiresAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const CUSTOMER_RECOVER_MUTATION = `#graphql
|
||||
mutation customerRecover($email: String!) {
|
||||
customerRecover(email: $email) {
|
||||
customerUserErrors {
|
||||
code
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const CUSTOMER_RESET_MUTATION = `#graphql
|
||||
mutation customerReset($id: ID!, $input: CustomerResetInput!) {
|
||||
customerReset(id: $id, input: $input) {
|
||||
customerAccessToken {
|
||||
accessToken
|
||||
expiresAt
|
||||
}
|
||||
customerUserErrors {
|
||||
code
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
76
lib/shopify/queries/user.ts
Normal file
76
lib/shopify/queries/user.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
export const CUSTOMER_QUERY = `#graphql
|
||||
query CustomerDetails(
|
||||
$customerAccessToken: String!
|
||||
$country: CountryCode
|
||||
$language: LanguageCode
|
||||
) @inContext(country: $country, language: $language) {
|
||||
customer(customerAccessToken: $customerAccessToken) {
|
||||
firstName
|
||||
lastName
|
||||
phone
|
||||
email
|
||||
defaultAddress {
|
||||
id
|
||||
formatted
|
||||
firstName
|
||||
lastName
|
||||
company
|
||||
address1
|
||||
address2
|
||||
country
|
||||
province
|
||||
city
|
||||
zip
|
||||
phone
|
||||
}
|
||||
addresses(first: 6) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
formatted
|
||||
firstName
|
||||
lastName
|
||||
company
|
||||
address1
|
||||
address2
|
||||
country
|
||||
province
|
||||
city
|
||||
zip
|
||||
phone
|
||||
}
|
||||
}
|
||||
}
|
||||
orders(first: 250, sortKey: PROCESSED_AT, reverse: true) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
orderNumber
|
||||
processedAt
|
||||
financialStatus
|
||||
fulfillmentStatus
|
||||
currentTotalPrice {
|
||||
amount
|
||||
currencyCode
|
||||
}
|
||||
lineItems(first: 2) {
|
||||
edges {
|
||||
node {
|
||||
variant {
|
||||
image {
|
||||
url
|
||||
altText
|
||||
height
|
||||
width
|
||||
}
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
@@ -263,3 +263,143 @@ export type ShopifyProductsOperation = {
|
||||
sortKey?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type Customer = {
|
||||
__typename?: 'Customer';
|
||||
/** Indicates whether the customer has consented to be sent marketing material via email. */
|
||||
acceptsMarketing: boolean;
|
||||
/** A list of addresses for the customer. */
|
||||
addresses: Maybe<string>;
|
||||
/** The date and time when the customer was created. */
|
||||
createdAt: string;
|
||||
/** The customer’s default address. */
|
||||
defaultAddress?: Maybe<string>;
|
||||
/** The customer’s name, email or phone number. */
|
||||
displayName: string;
|
||||
/** The customer’s email address. */
|
||||
email?: Maybe<string>;
|
||||
/** The customer’s first name. */
|
||||
firstName?: Maybe<string>;
|
||||
/** A unique identifier for the customer. */
|
||||
id: string;
|
||||
/** The customer's most recently updated, incomplete checkout. */
|
||||
/** The customer’s last name. */
|
||||
lastName?: Maybe<string>;
|
||||
/** Returns a metafield found by namespace and key. */
|
||||
/**
|
||||
* The metafields associated with the resource matching the supplied list of namespaces and keys.
|
||||
*
|
||||
*/
|
||||
/** The number of orders that the customer has made at the store in their lifetime. */
|
||||
numberOfOrders: string;
|
||||
/** The orders associated with the customer. */
|
||||
/** The customer’s phone number. */
|
||||
phone?: Maybe<string>;
|
||||
/**
|
||||
* A comma separated list of tags that have been added to the customer.
|
||||
* Additional access scope required: unauthenticated_read_customer_tags.
|
||||
*
|
||||
*/
|
||||
tags: Array<string>;
|
||||
/** The date and time when the customer information was updated. */
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type Scalars = {
|
||||
ID: string;
|
||||
String: string;
|
||||
Boolean: boolean;
|
||||
Int: number;
|
||||
Float: number;
|
||||
Color: string;
|
||||
DateTime: string;
|
||||
Decimal: string;
|
||||
HTML: string;
|
||||
JSON: unknown;
|
||||
URL: string;
|
||||
UnsignedInt64: string;
|
||||
};
|
||||
|
||||
export type DisplayableError = {
|
||||
/** The path to the input field that caused the error. */
|
||||
field?: Maybe<Array<Scalars['String']>>;
|
||||
/** The error message. */
|
||||
message: Scalars['String'];
|
||||
};
|
||||
|
||||
export type CustomerAccessToken = {
|
||||
__typename?: 'CustomerAccessToken';
|
||||
/** The customer’s access token. */
|
||||
accessToken: Scalars['String'];
|
||||
/** The date and time when the customer access token expires. */
|
||||
expiresAt: Scalars['DateTime'];
|
||||
};
|
||||
|
||||
export type CustomerUserError = DisplayableError & {
|
||||
__typename?: 'CustomerUserError';
|
||||
/** The error code. */
|
||||
code?: Maybe<any>;
|
||||
/** The path to the input field that caused the error. */
|
||||
field?: Maybe<Array<Scalars['String']>>;
|
||||
/** The error message. */
|
||||
message: Scalars['String'];
|
||||
};
|
||||
|
||||
export type UserError = DisplayableError & {
|
||||
__typename?: 'UserError';
|
||||
/** The path to the input field that caused the error. */
|
||||
field?: Maybe<Array<Scalars['String']>>;
|
||||
/** The error message. */
|
||||
message: Scalars['String'];
|
||||
};
|
||||
|
||||
export type CustomerAccessTokenCreatePayload = {
|
||||
__typename?: 'CustomerAccessTokenCreatePayload';
|
||||
/** The newly created customer access token object. */
|
||||
customerAccessToken?: Maybe<CustomerAccessToken>;
|
||||
/** The list of errors that occurred from executing the mutation. */
|
||||
customerUserErrors: Array<CustomerUserError>;
|
||||
/**
|
||||
* The list of errors that occurred from executing the mutation.
|
||||
* @deprecated Use `customerUserErrors` instead.
|
||||
*/
|
||||
userErrors: Array<UserError>;
|
||||
};
|
||||
|
||||
/** Return type for `customerCreate` mutation. */
|
||||
export type CustomerCreatePayload = {
|
||||
__typename?: 'CustomerCreatePayload';
|
||||
/** The created customer object. */
|
||||
customer?: Maybe<Customer>;
|
||||
/** The list of errors that occurred from executing the mutation. */
|
||||
/**
|
||||
* The list of errors that occurred from executing the mutation.
|
||||
* @deprecated Use `customerUserErrors` instead.
|
||||
*/
|
||||
};
|
||||
|
||||
export type CustomerRecoverPayload = {
|
||||
__typename?: 'CustomerRecoverPayload';
|
||||
/** The list of errors that occurred from executing the mutation. */
|
||||
customerUserErrors: Array<CustomerUserError>;
|
||||
/**
|
||||
* The list of errors that occurred from executing the mutation.
|
||||
* @deprecated Use `customerUserErrors` instead.
|
||||
*/
|
||||
userErrors: Array<UserError>;
|
||||
};
|
||||
|
||||
export type CustomerResetPayload = {
|
||||
__typename?: 'CustomerResetPayload';
|
||||
/** The customer object which was reset. */
|
||||
customer?: Maybe<Customer>;
|
||||
/** A newly created customer access token object for the customer. */
|
||||
customerAccessToken?: Maybe<CustomerAccessToken>;
|
||||
/** The list of errors that occurred from executing the mutation. */
|
||||
customerUserErrors: Array<CustomerUserError>;
|
||||
/**
|
||||
* The list of errors that occurred from executing the mutation.
|
||||
* @deprecated Use `customerUserErrors` instead.
|
||||
*/
|
||||
userErrors: Array<UserError>;
|
||||
};
|
||||
|
Reference in New Issue
Block a user