feat(medusa): Authentication overhaul (#4064)

* implemented bearer auth

* changed naming strat

* changed session auth to not use jwt

* typo

* changed auth header prefix for admin api token auth

* fixed supporting functions to work with new session type

* removed database calls for bearer auth improving performance

* removed unused deps

* changed auth in tests

* added integration tests

* Accepted suggested change

Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>

* Typo

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* more typos

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* proper formatting

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* removed endregion

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* removed startregion

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* fixed admin JWT integration test

* added more fixes to integration tests

* Update OAS

* Create fluffy-donkeys-hope.md

* created API reference for new auth

* implemented getToken in medusa-js

* Apply suggestions from code review

Co-authored-by: Shahed Nasser <shahednasser@gmail.com>

* Apply suggestions from code review

Co-authored-by: Shahed Nasser <shahednasser@gmail.com>

* deleted files which should be autogenerated

* Update fluffy-donkeys-hope.md

* JSDoc update

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>

* added missing route exports

* implemented runtime domain safety in jwt token manager

* fixed jwt manager

* lint get-token files

* Update fluffy-donkeys-hope.md

* Revert "deleted files which should be autogenerated"

This reverts commit cd5e86623b822e6a6ac37322b952143ccc493df9.

* Revert "Apply suggestions from code review"

This reverts commit f02f07ce58fd9fcc2dfc80cadbb9df2665108d65.

* Revert "created API reference for new auth"

This reverts commit c9eafbb36453f5cf8047c79e94f470cb2d023c7d.

* renamed header for sending api access tokens

* medusa-js - changed apiKey header

---------

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
Co-authored-by: olivermrbl <oliver@mrbltech.com>
Co-authored-by: Shahed Nasser <shahednasser@gmail.com>
This commit is contained in:
David Preininger
2023-09-25 13:57:44 -04:00
committed by GitHub
co-authored by Carlos R. L. Rodrigues Oliver Windall Juhl Shahed Nasser olivermrbl
parent 07e65f5aba
commit 2caff2efc7
98 changed files with 864 additions and 351 deletions
@@ -0,0 +1,11 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import { SetRelation, Merge } from "../core/ModelUtils"
export interface AdminBearerAuthRes {
/**
* Access token for subsequent authorization.
*/
accessToken?: string
}
@@ -0,0 +1,11 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import { SetRelation, Merge } from "../core/ModelUtils"
export interface StoreBearerAuthRes {
/**
* Access token for subsequent authorization.
*/
accessToken?: string
}
@@ -9,6 +9,7 @@ export type { AdminAppsRes } from "./AdminAppsRes"
export type { AdminAuthRes } from "./AdminAuthRes"
export type { AdminBatchJobListRes } from "./AdminBatchJobListRes"
export type { AdminBatchJobRes } from "./AdminBatchJobRes"
export type { AdminBearerAuthRes } from "./AdminBearerAuthRes"
export type { AdminCollectionsDeleteRes } from "./AdminCollectionsDeleteRes"
export type { AdminCollectionsListRes } from "./AdminCollectionsListRes"
export type { AdminCollectionsRes } from "./AdminCollectionsRes"
@@ -396,6 +397,7 @@ export type { StockLocationDTO } from "./StockLocationDTO"
export type { StockLocationExpandedDTO } from "./StockLocationExpandedDTO"
export type { Store } from "./Store"
export type { StoreAuthRes } from "./StoreAuthRes"
export type { StoreBearerAuthRes } from "./StoreBearerAuthRes"
export type { StoreCartShippingOptionsListRes } from "./StoreCartShippingOptionsListRes"
export type { StoreCartsRes } from "./StoreCartsRes"
export type { StoreCollectionsListRes } from "./StoreCollectionsListRes"
@@ -0,0 +1,38 @@
/**
* `JwtTokenManager` holds JWT tokens in state.
*/
class JwtTokenManager {
private adminJwt: string | null = null;
private storeJwt: string | null = null;
/**
* Set a store or admin jwt token to be sent with each request.
*/
public registerJwt(token: string, domain: "admin" | "store") {
if (domain === "admin") {
this.adminJwt = token;
} else if (domain === "store") {
this.storeJwt = token;
} else {
throw new Error(`'domain' must be wither 'admin' or 'store' received ${domain}`)
}
}
/**
* Retrieve the store or admin jwt token
*/
public getJwt(domain: "admin" | "store") {
if (domain === "admin") {
return this.adminJwt;
} else if (domain === "store") {
return this.storeJwt;
} else {
throw new Error(`'domain' must be wither 'admin' or 'store' received ${domain}`)
}
}
}
/**
* Export singleton instance.
*/
export default new JwtTokenManager()
+11 -1
View File
@@ -3,6 +3,7 @@ import * as rax from "retry-axios"
import { v4 as uuidv4 } from "uuid"
import KeyManager from "./key-manager"
import JwtTokenManager from "./jwt-token-manager"
const unAuthenticatedAdminEndpoints = {
"/admin/auth": "POST",
@@ -125,7 +126,16 @@ class Client {
if (this.config.apiKey && this.requiresAuthentication(path, method)) {
defaultHeaders = {
...defaultHeaders,
Authorization: `Bearer ${this.config.apiKey}`,
"x-medusa-access-token": this.config.apiKey,
}
}
const domain: "admin" | "store" = path.includes("admin") ? "admin" : "store"
if (JwtTokenManager.getJwt(domain)) {
defaultHeaders = {
...defaultHeaders,
Authorization: `Bearer ${JwtTokenManager.getJwt(domain)}`,
}
}
+21 -1
View File
@@ -1,5 +1,6 @@
import { AdminAuthRes, AdminPostAuthReq } from "@medusajs/medusa"
import { AdminAuthRes, AdminPostAuthReq, AdminBearerAuthRes } from "@medusajs/medusa"
import { ResponsePromise } from "../../typings"
import JwtTokenManager from "../../jwt-token-manager"
import BaseResource from "../base"
class AdminAuthResource extends BaseResource {
@@ -41,6 +42,25 @@ class AdminAuthResource extends BaseResource {
const path = `/admin/auth`
return this.client.request("POST", path, payload, {}, customHeaders)
}
/**
* @description Retrieves a new JWT access token
* @param {AdminPostAuthReq} payload
* @param customHeaders
* @return {ResponsePromise<AdminBearerAuthRes>}
*/
getToken(
payload: AdminPostAuthReq,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminBearerAuthRes> {
const path = `/admin/auth/token`
return this.client.request("POST", path, payload, {}, customHeaders)
.then((res) => {
JwtTokenManager.registerJwt(res.access_token, "admin");
return res
});
}
}
export default AdminAuthResource
+21
View File
@@ -2,8 +2,10 @@ import {
StoreGetAuthEmailRes,
StorePostAuthReq,
StoreAuthRes,
StoreBearerAuthRes,
} from "@medusajs/medusa"
import { ResponsePromise } from "../typings"
import JwtTokenManager from "../jwt-token-manager"
import BaseResource from "./base"
class AuthResource extends BaseResource {
@@ -48,6 +50,25 @@ class AuthResource extends BaseResource {
const path = `/store/auth/${email}`
return this.client.request("GET", path, undefined, {}, customHeaders)
}
/**
* @description Retrieves a new JWT access token
* @param {AdminPostAuthReq} payload
* @param customHeaders
* @return {ResponsePromise<AdminBearerAuthRes>}
*/
getToken(
payload: StorePostAuthReq,
customHeaders: Record<string, any> = {}
): ResponsePromise<StoreBearerAuthRes> {
const path = `/store/auth/token`
return this.client.request("POST", path, payload, {}, customHeaders)
.then((res) => {
JwtTokenManager.registerJwt(res.data.access_token, "store");
return res
});
}
}
export default AuthResource
+1 -1
View File
@@ -83,7 +83,7 @@
"node-schedule": "^2.1.1",
"papaparse": "5.3.2",
"passport": "^0.6.0",
"passport-http-bearer": "^1.0.1",
"passport-custom": "^1.1.1",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"pg": "^8.11.2",
@@ -7,7 +7,7 @@ import passport from "passport"
export default (): RequestHandler => {
return (req: Request, res: Response, next: NextFunction): void => {
passport.authenticate(
["store-jwt", "bearer"],
["store-session", "store-bearer"],
{ session: false },
(err, user) => {
if (err) {
@@ -3,7 +3,7 @@ import passport from "passport"
export default (): RequestHandler => {
return (req: Request, res: Response, next: NextFunction): void => {
passport.authenticate(["admin-jwt", "bearer"], { session: false })(
passport.authenticate(["admin-session", "admin-bearer", "admin-api-token"], { session: false })(
req,
res,
next
@@ -7,7 +7,7 @@ export default (): RequestHandler => {
return next()
}
passport.authenticate(["store-jwt", "bearer"], { session: false })(
passport.authenticate(["store-session", "store-bearer"], { session: false })(
req,
res,
next
@@ -66,15 +66,6 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/responses/500_error"
*/
export default async (req, res) => {
const {
projectConfig: { jwt_secret },
} = req.scope.resolve("configModule")
if (!jwt_secret) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
"Please configure jwt_secret in your environment"
)
}
const validated = await validator(AdminPostAuthReq, req.body)
const authService: AuthService = req.scope.resolve("authService")
@@ -86,10 +77,8 @@ export default async (req, res) => {
})
if (result.success && result.user) {
// Add JWT to cookie
req.session.jwt = jwt.sign({ userId: result.user.id }, jwt_secret, {
expiresIn: "24h",
})
// Set user id on session, this is stored on the server.
req.session.user_id = result.user.id
const cleanRes = _.omit(result.user, ["password_hash"])
@@ -42,6 +42,11 @@
* $ref: "#/components/responses/500_error"
*/
export default async (req, res) => {
req.session.destroy()
res.status(200).end()
if (req.session.customer_id) { // if we are also logged in as a customer, persist that session
delete req.session.user_id
} else { // otherwise, destroy the session
req.session.destroy()
}
res.sendStatus(200)
}
@@ -52,8 +52,10 @@ import _ from "lodash"
*/
export default async (req, res) => {
try {
const userId = req.user.id || req.user.userId
const userService: UserService = req.scope.resolve("userService")
const user = await userService.retrieve(req.user.userId)
const user = await userService.retrieve(userId)
const cleanRes = _.omit(user, ["password_hash"])
res.status(200).json({ user: cleanRes })
@@ -0,0 +1,102 @@
import jwt from "jsonwebtoken"
import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import AuthService from "../../../../services/auth"
import { validator } from "../../../../utils/validator"
import { AdminPostAuthReq } from "./create-session"
/**
* @oas [post] /admin/token
* operationId: "PostToken"
* summary: "User Login (JWT)"
* x-authenticated: false
* description: "After a successful login, a JWT token is returned for subsequent authorization."
* parameters:
* - (body) email=* {string} The User's email.
* - (body) password=* {string} The User's password.
* requestBody:
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/AdminPostAuthReq"
* x-codegen:
* method: getToken
* x-codeSamples:
* - lang: JavaScript
* label: JS Client
* source: |
* import Medusa from "@medusajs/medusa-js"
* const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
* medusa.admin.auth.getToken({
* email: 'user@example.com',
* password: 'supersecret'
* })
* .then(({ accessToken }) => {
* console.log(accessToekn);
* });
* - lang: Shell
* label: cURL
* source: |
* curl --location --request POST 'https://medusa-url.com/admin/auth/token' \
* --header 'Content-Type: application/json' \
* --data-raw '{
* "email": "user@example.com",
* "password": "supersecret"
* }'
* tags:
* - Auth
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/AdminBearerAuthRes"
* "400":
* $ref: "#/components/responses/400_error"
* "401":
* $ref: "#/components/responses/incorrect_credentials"
* "404":
* $ref: "#/components/responses/not_found_error"
* "409":
* $ref: "#/components/responses/invalid_state_error"
* "422":
* $ref: "#/components/responses/invalid_request_error"
* "500":
* $ref: "#/components/responses/500_error"
*/
export default async (req, res) => {
const {
projectConfig: { jwt_secret },
} = req.scope.resolve("configModule")
if (!jwt_secret) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
"Please configure jwt_secret in your environment"
)
}
const validated = await validator(AdminPostAuthReq, req.body)
const authService: AuthService = req.scope.resolve("authService")
const manager: EntityManager = req.scope.resolve("manager")
const result = await manager.transaction(async (transactionManager) => {
return await authService
.withTransaction(transactionManager)
.authenticate(validated.email, validated.password)
})
if (result.success && result.user) {
// Create jwt token to send back
const token = jwt.sign(
{ user_id: result.user.id, domain: "admin" },
jwt_secret,
{
expiresIn: "24h",
}
)
res.json({ access_token: token })
} else {
res.sendStatus(401)
}
}
@@ -12,6 +12,7 @@ export default (app) => {
middlewares.authenticate(),
middlewares.wrap(require("./get-session").default)
)
route.post("/", middlewares.wrap(require("./create-session").default))
route.delete(
@@ -20,6 +21,8 @@ export default (app) => {
middlewares.wrap(require("./delete-session").default)
)
route.post("/token", middlewares.wrap(require("./get-token").default))
return app
}
@@ -37,6 +40,19 @@ export type AdminAuthRes = {
user: Omit<User, "password_hash">
}
/**
* @schema AdminBearerAuthRes
* type: object
* properties:
* accessToken:
* description: Access token for subsequent authorization.
* type: string
*/
export type AdminBearerAuthRes = {
access_token: string
}
export * from "./create-session"
export * from "./delete-session"
export * from "./get-session"
export * from "./get-token"
@@ -9,7 +9,7 @@ describe("POST /invites/:invite_id/resend", () => {
subject = await request("POST", `/admin/invites/invite_test/resend`, {
adminSession: {
jwt: {
id: "test_user",
userId: "test_user",
},
},
})
@@ -79,17 +79,8 @@ export default async (req, res) => {
return
}
// Add JWT to cookie
const {
projectConfig: { jwt_secret },
} = req.scope.resolve("configModule")
req.session.jwt_store = jwt.sign(
{ customer_id: result.customer?.id },
jwt_secret!,
{
expiresIn: "30d",
}
)
// Set customer id on session, this is stored on the server.
req.session.customer_id = result.customer?.id
const customerService: CustomerService = req.scope.resolve("customerService")
const customer = await customerService.retrieve(result.customer?.id || "", {
@@ -33,6 +33,11 @@
* $ref: "#/components/responses/500_error"
*/
export default async (req, res) => {
req.session.jwt_store = {}
res.json({})
if(req.session.user_id) { // if we are also logged in as a user, persist that session
delete req.session.customer_id
} else { // otherwise, destroy the session
req.session.destroy()
}
res.sendStatus(200)
}
@@ -0,0 +1,102 @@
import jwt from "jsonwebtoken"
import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import AuthService from "../../../../services/auth"
import { validator } from "../../../../utils/validator"
import { StorePostAuthReq } from "./create-session"
/**
* @oas [post] /store/token
* operationId: "PostToken"
* summary: "Customer Login (JWT)"
* x-authenticated: false
* description: "After a successful login, a JWT token is returned for subsequent authorization."
* parameters:
* - (body) email=* {string} The User's email.
* - (body) password=* {string} The User's password.
* requestBody:
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/StorePostAuthReq"
* x-codegen:
* method: getToken
* x-codeSamples:
* - lang: JavaScript
* label: JS Client
* source: |
* import Medusa from "@medusajs/medusa-js"
* const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
* medusa.store.auth.getToken({
* email: 'user@example.com',
* password: 'supersecret'
* })
* .then(({ accessToken }) => {
* console.log(accessToken);
* });
* - lang: Shell
* label: cURL
* source: |
* curl --location --request POST 'https://medusa-url.com/store/auth/token' \
* --header 'Content-Type: application/json' \
* --data-raw '{
* "email": "user@example.com",
* "password": "supersecret"
* }'
* tags:
* - Auth
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/StoreBearerAuthRes"
* "400":
* $ref: "#/components/responses/400_error"
* "401":
* $ref: "#/components/responses/incorrect_credentials"
* "404":
* $ref: "#/components/responses/not_found_error"
* "409":
* $ref: "#/components/responses/invalid_state_error"
* "422":
* $ref: "#/components/responses/invalid_request_error"
* "500":
* $ref: "#/components/responses/500_error"
*/
export default async (req, res) => {
const {
projectConfig: { jwt_secret },
} = req.scope.resolve("configModule")
if (!jwt_secret) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
"Please configure jwt_secret in your environment"
)
}
const validated = await validator(StorePostAuthReq, req.body)
const authService: AuthService = req.scope.resolve("authService")
const manager: EntityManager = req.scope.resolve("manager")
const result = await manager.transaction(async (transactionManager) => {
return await authService
.withTransaction(transactionManager)
.authenticateCustomer(validated.email, validated.password)
})
if (result.success && result.customer) {
// Create jwt token to send back
const token = jwt.sign(
{ customer_id: result.customer.id, domain: "store" },
jwt_secret,
{
expiresIn: "30d",
}
)
res.json({ access_token: token })
} else {
res.sendStatus(401)
}
}
@@ -15,6 +15,7 @@ export default (app) => {
route.get("/:email", middlewares.wrap(require("./exists").default))
route.delete("/", middlewares.wrap(require("./delete-session").default))
route.post("/", middlewares.wrap(require("./create-session").default))
route.post("/token", middlewares.wrap(require("./get-token").default))
return app
}
@@ -41,6 +42,18 @@ export type StoreAuthRes = {
customer: Customer
}
/**
* @schema StoreBearerAuthRes
* type: object
* properties:
* accessToken:
* description: Access token for subsequent authorization.
* type: string
*/
export type StoreBearerAuthRes = {
access_token: string
}
/**
* @schema StoreGetAuthEmailRes
* type: object
@@ -59,3 +72,4 @@ export * from "./create-session"
export * from "./delete-session"
export * from "./exists"
export * from "./get-session"
export * from "./get-token"
@@ -103,13 +103,7 @@ export default async (req, res) => {
select: defaultStoreCustomersFields,
})
// Add JWT to cookie
const {
projectConfig: { jwt_secret },
} = req.scope.resolve("configModule")
req.session.jwt_store = jwt.sign({ customer_id: customer.id }, jwt_secret!, {
expiresIn: "30d",
})
req.session.customer_id = customer.id
res.status(200).json({ customer })
}
+11 -22
View File
@@ -84,7 +84,7 @@ container.register("modulesHelper", asValue(moduleHelper))
container.register("configModule", asValue(config))
container.register({
logger: asValue({
error: () => {},
error: () => { },
}),
manager: asValue(MockManager),
})
@@ -145,31 +145,20 @@ export async function request(method, url, opts = {}) {
)
headers.Cookie = headers.Cookie || ""
if (opts.adminSession) {
const adminSession = { ...opts.adminSession }
const token = jwt.sign(
{ user_id: opts.adminSession.userId || opts.adminSession.jwt?.userId, domain: "admin" },
config.projectConfig.jwt_secret
)
if (adminSession.jwt) {
adminSession.jwt = jwt.sign(
adminSession.jwt,
config.projectConfig.jwt_secret,
{
expiresIn: "30m",
}
)
}
headers.Cookie = JSON.stringify(adminSession) || ""
headers.Authorization = `Bearer ${token}`
}
if (opts.clientSession) {
if (opts.clientSession.jwt) {
opts.clientSession.jwt_store = jwt.sign(
opts.clientSession.jwt,
config.projectConfig.jwt_secret,
{
expiresIn: "30d",
}
)
}
const token = jwt.sign(
{ customer_id: opts.clientSession.customer_id || opts.clientSession.jwt?.customer_id, domain: "store" },
config.projectConfig.jwt_secret
)
headers.Cookie = JSON.stringify(opts.clientSession) || ""
headers.Authorization = `Bearer ${token}`
}
for (const name in headers) {
+84 -22
View File
@@ -1,8 +1,8 @@
import { Express } from "express"
import passport from "passport"
import { Strategy as BearerStrategy } from "passport-http-bearer"
import { Strategy as JWTStrategy } from "passport-jwt"
import { Strategy as JWTStrategy, ExtractJwt } from "passport-jwt"
import { Strategy as LocalStrategy } from "passport-local"
import { Strategy as CustomStrategy } from "passport-custom"
import { AuthService } from "../services"
import { ConfigModule, MedusaContainer } from "../types/global"
@@ -46,43 +46,105 @@ export default async ({
// calls will be authenticated based on the JWT
const { jwt_secret } = configModule.projectConfig
passport.use(
"admin-jwt",
new JWTStrategy(
{
jwtFromRequest: (req) => req.session.jwt,
secretOrKey: jwt_secret,
},
async (jwtPayload, done) => {
return done(null, jwtPayload)
"admin-session",
new CustomStrategy(
async (req, done) => {
// @ts-ignore
if(req.session?.user_id) {
// @ts-ignore
return done(null, { userId: req.session.user_id })
}
return done(null, false)
}
)
)
passport.use(
"store-jwt",
new JWTStrategy(
{
jwtFromRequest: (req) => req.session.jwt_store,
secretOrKey: jwt_secret,
},
async (jwtPayload, done) => {
return done(null, jwtPayload)
"store-session",
new CustomStrategy(
async (req, done) => {
// @ts-ignore
if(req.session?.customer_id) {
// @ts-ignore
return done(null, { customer_id: req.session.customer_id })
}
return done(null, false)
}
)
)
// Alternatively use bearer token to authenticate to the admin api
// Alternatively use API token to authenticate to the admin api
passport.use(
new BearerStrategy(async (token, done) => {
const auth = await authService.authenticateAPIToken(token)
"admin-api-token",
new CustomStrategy(async (req, done) => {
// extract the token from the header
const token = req.headers["x-medusa-access-token"];
// check if header exists and is string
// typescript will complain if we don't check for type
if (!token || typeof token !== "string") {
return done(null, false)
}
const auth = await authService.authenticateAPIToken(token);
if (auth.success) {
done(null, auth.user)
} else {
done(auth.error)
done(null, false)
}
})
)
// Admin bearer JWT token authentication strategy, best suited for web SPAs or mobile apps
passport.use(
"admin-bearer",
new JWTStrategy(
{
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: jwt_secret,
},
(token, done) => {
if (token.domain !== "admin") {
done(null, false)
return
}
if (!token.user_id) {
done(null, false)
return
}
done(null, { userId: token.user_id })
}
)
)
// Store bearer JWT token authentication strategy, best suited for web SPAs or mobile apps
passport.use(
"store-bearer",
new JWTStrategy(
{
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: jwt_secret,
},
(token, done) => {
if (token.domain !== "store") {
done(null, false)
return
}
if (!token.customer_id) {
done(null, false)
return
}
done(null, { customer_id: token.customer_id })
}
)
)
app.use(passport.initialize())
app.use(passport.session())
}
+1 -15
View File
@@ -51,20 +51,6 @@ class AuthService extends TransactionBaseService {
*/
async authenticateAPIToken(token: string): Promise<AuthenticateResult> {
return await this.atomicPhase_(async (transactionManager) => {
if (process.env.NODE_ENV?.startsWith("dev")) {
try {
const user: User = await this.userService_
.withTransaction(transactionManager)
.retrieve(token)
return {
success: true,
user,
}
} catch (error) {
// ignore
}
}
try {
const user: User = await this.userService_
.withTransaction(transactionManager)
@@ -138,7 +124,7 @@ class AuthService extends TransactionBaseService {
* @param {string} password - the password of the user
* @return {{ success: (bool), customer: (object | undefined) }}
* success: whether authentication succeeded
* user: the user document if authentication succeeded
* customer: the customer document if authentication succeded
* error: a string with the error message
*/
async authenticateCustomer(