auth proccess

This commit is contained in:
brkcvn
2023-11-15 12:36:17 +03:00
parent 27facd7520
commit 77408259d2
19 changed files with 1088 additions and 22 deletions

8
lib/isAuthenticated.ts Normal file
View 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;

View File

@@ -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,

View 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
}
}
}
`;

View 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
}
}
}
}
}
}
}
}
`;

View File

@@ -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 customers default address. */
defaultAddress?: Maybe<string>;
/** The customers name, email or phone number. */
displayName: string;
/** The customers email address. */
email?: Maybe<string>;
/** The customers first name. */
firstName?: Maybe<string>;
/** A unique identifier for the customer. */
id: string;
/** The customer's most recently updated, incomplete checkout. */
/** The customers 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 customers 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 customers 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>;
};