feat(auth): Make token auth default (#6305)
**What** - make token auth the default being returned from authentication endpoints in api-v2 - Add `auth/session` to convert token to session based auth - add regex-scopes to authenticate middleware Co-authored-by: Sebastian Rindom <7554214+srindom@users.noreply.github.com>
This commit is contained in:
1 parent
96ba49329b
commit
e2738ab91d
21 files changed
+147
-138
No files matched your search
@@ -1,11 +1,12 @@
|
|||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
|
||||||
import { ICustomerModuleService } from "@medusajs/types"
|
import { ICustomerModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
import { useApi } from "../../../../environment-helpers/use-api"
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
import { getContainer } from "../../../../environment-helpers/use-container"
|
|
||||||
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
|
||||||
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
|
||||||
|
|
||||||
jest.setTimeout(50000)
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
@@ -39,9 +40,11 @@ describe("POST /store/customers/me/addresses", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should create a customer address", async () => {
|
it("should create a customer address", async () => {
|
||||||
|
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
|
||||||
const { customer, jwt } = await createAuthenticatedCustomer(
|
const { customer, jwt } = await createAuthenticatedCustomer(
|
||||||
customerModuleService,
|
customerModuleService,
|
||||||
appContainer.resolve(ModuleRegistrationName.AUTH)
|
appContainer.resolve(ModuleRegistrationName.AUTH),
|
||||||
|
jwt_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
const api = useApi() as any
|
const api = useApi() as any
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
|||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
import adminSeeder from "../../../../helpers/admin-seeder"
|
import adminSeeder from "../../../../helpers/admin-seeder"
|
||||||
import { getContainer } from "../../../../environment-helpers/use-container"
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
|
import jwt from "jsonwebtoken"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
import { useApi } from "../../../../environment-helpers/use-api"
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
@@ -47,12 +48,14 @@ describe("POST /store/customers", () => {
|
|||||||
const authService: IAuthModuleService = appContainer.resolve(
|
const authService: IAuthModuleService = appContainer.resolve(
|
||||||
ModuleRegistrationName.AUTH
|
ModuleRegistrationName.AUTH
|
||||||
)
|
)
|
||||||
|
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
|
||||||
const authUser = await authService.createAuthUser({
|
const authUser = await authService.createAuthUser({
|
||||||
entity_id: "store_user",
|
entity_id: "store_user",
|
||||||
provider_id: "test",
|
provider: "emailpass",
|
||||||
scope: "store",
|
scope: "store",
|
||||||
})
|
})
|
||||||
const jwt = await authService.generateJwtToken(authUser.id, "store")
|
|
||||||
|
const token = jwt.sign(authUser, jwt_secret)
|
||||||
|
|
||||||
const api = useApi() as any
|
const api = useApi() as any
|
||||||
const response = await api.post(
|
const response = await api.post(
|
||||||
@@ -62,7 +65,7 @@ describe("POST /store/customers", () => {
|
|||||||
last_name: "Doe",
|
last_name: "Doe",
|
||||||
email: "john@me.com",
|
email: "john@me.com",
|
||||||
},
|
},
|
||||||
{ headers: { authorization: `Bearer ${jwt}` } }
|
{ headers: { authorization: `Bearer ${token}` } }
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
|
||||||
import { ICustomerModuleService } from "@medusajs/types"
|
import { ICustomerModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
import { useApi } from "../../../../environment-helpers/use-api"
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
import { getContainer } from "../../../../environment-helpers/use-container"
|
|
||||||
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
|
||||||
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
|
||||||
|
|
||||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
|
||||||
@@ -25,6 +26,14 @@ describe("DELETE /store/customers/me/addresses/:address_id", () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO: delete with removal of authProvider
|
||||||
|
beforeEach(async () => {
|
||||||
|
const onStart =
|
||||||
|
appContainer.resolve(ModuleRegistrationName.AUTH).__hooks
|
||||||
|
.onApplicationStart ?? (() => Promise.resolve())
|
||||||
|
await onStart()
|
||||||
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
const db = useDb()
|
const db = useDb()
|
||||||
await db.shutdown()
|
await db.shutdown()
|
||||||
@@ -37,9 +46,11 @@ describe("DELETE /store/customers/me/addresses/:address_id", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should delete a customer address", async () => {
|
it("should delete a customer address", async () => {
|
||||||
|
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
|
||||||
const { customer, jwt } = await createAuthenticatedCustomer(
|
const { customer, jwt } = await createAuthenticatedCustomer(
|
||||||
customerModuleService,
|
customerModuleService,
|
||||||
appContainer.resolve(ModuleRegistrationName.AUTH)
|
appContainer.resolve(ModuleRegistrationName.AUTH),
|
||||||
|
jwt_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
const address = await customerModuleService.addAddresses({
|
const address = await customerModuleService.addAddresses({
|
||||||
@@ -65,9 +76,11 @@ describe("DELETE /store/customers/me/addresses/:address_id", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should fail to delete another customer's address", async () => {
|
it("should fail to delete another customer's address", async () => {
|
||||||
|
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
|
||||||
const { jwt } = await createAuthenticatedCustomer(
|
const { jwt } = await createAuthenticatedCustomer(
|
||||||
customerModuleService,
|
customerModuleService,
|
||||||
appContainer.resolve(ModuleRegistrationName.AUTH)
|
appContainer.resolve(ModuleRegistrationName.AUTH),
|
||||||
|
jwt_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
const otherCustomer = await customerModuleService.create({
|
const otherCustomer = await customerModuleService.create({
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
|
||||||
import { ICustomerModuleService } from "@medusajs/types"
|
import { ICustomerModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
||||||
|
import customer from "../../../../development/database/customer"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
import { useApi } from "../../../../environment-helpers/use-api"
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
import { getContainer } from "../../../../environment-helpers/use-container"
|
|
||||||
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
|
||||||
import adminSeeder from "../../../../helpers/admin-seeder"
|
|
||||||
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
|
||||||
|
|
||||||
jest.setTimeout(50000)
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
@@ -34,19 +35,17 @@ describe("GET /store/customers", () => {
|
|||||||
await shutdownServer()
|
await shutdownServer()
|
||||||
})
|
})
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await adminSeeder(dbConnection)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
const db = useDb()
|
const db = useDb()
|
||||||
await db.teardown()
|
await db.teardown()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should retrieve auth user's customer", async () => {
|
it("should retrieve auth user's customer", async () => {
|
||||||
|
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
|
||||||
const { customer, jwt } = await createAuthenticatedCustomer(
|
const { customer, jwt } = await createAuthenticatedCustomer(
|
||||||
customerModuleService,
|
customerModuleService,
|
||||||
appContainer.resolve(ModuleRegistrationName.AUTH)
|
appContainer.resolve(ModuleRegistrationName.AUTH),
|
||||||
|
jwt_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
const api = useApi() as any
|
const api = useApi() as any
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
|
||||||
import { ICustomerModuleService } from "@medusajs/types"
|
import { ICustomerModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
import { useApi } from "../../../../environment-helpers/use-api"
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
import { getContainer } from "../../../../environment-helpers/use-container"
|
|
||||||
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
|
||||||
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
|
||||||
|
|
||||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
|
||||||
@@ -43,9 +44,11 @@ describe("GET /store/customers/me/addresses", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should get all customer addresses and its count", async () => {
|
it("should get all customer addresses and its count", async () => {
|
||||||
|
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
|
||||||
const { customer, jwt } = await createAuthenticatedCustomer(
|
const { customer, jwt } = await createAuthenticatedCustomer(
|
||||||
customerModuleService,
|
customerModuleService,
|
||||||
appContainer.resolve(ModuleRegistrationName.AUTH)
|
appContainer.resolve(ModuleRegistrationName.AUTH),
|
||||||
|
jwt_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
await customerModuleService.addAddresses([
|
await customerModuleService.addAddresses([
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
|
||||||
import { ICustomerModuleService } from "@medusajs/types"
|
import { ICustomerModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
import { useApi } from "../../../../environment-helpers/use-api"
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
import { getContainer } from "../../../../environment-helpers/use-container"
|
|
||||||
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
|
||||||
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
|
||||||
|
|
||||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
|
||||||
@@ -25,6 +26,14 @@ describe("POST /store/customers/:id/addresses/:address_id", () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO: delete with removal of authProvider
|
||||||
|
beforeEach(async () => {
|
||||||
|
const onStart =
|
||||||
|
appContainer.resolve(ModuleRegistrationName.AUTH).__hooks
|
||||||
|
.onApplicationStart ?? (() => Promise.resolve())
|
||||||
|
await onStart()
|
||||||
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
const db = useDb()
|
const db = useDb()
|
||||||
await db.shutdown()
|
await db.shutdown()
|
||||||
@@ -37,9 +46,12 @@ describe("POST /store/customers/:id/addresses/:address_id", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should update a customer address", async () => {
|
it("should update a customer address", async () => {
|
||||||
|
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
|
||||||
|
|
||||||
const { customer, jwt } = await createAuthenticatedCustomer(
|
const { customer, jwt } = await createAuthenticatedCustomer(
|
||||||
customerModuleService,
|
customerModuleService,
|
||||||
appContainer.resolve(ModuleRegistrationName.AUTH)
|
appContainer.resolve(ModuleRegistrationName.AUTH),
|
||||||
|
jwt_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
const address = await customerModuleService.addAddresses({
|
const address = await customerModuleService.addAddresses({
|
||||||
@@ -69,15 +81,19 @@ describe("POST /store/customers/:id/addresses/:address_id", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should fail to update another customer's address", async () => {
|
it("should fail to update another customer's address", async () => {
|
||||||
|
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
|
||||||
|
|
||||||
const { jwt } = await createAuthenticatedCustomer(
|
const { jwt } = await createAuthenticatedCustomer(
|
||||||
customerModuleService,
|
customerModuleService,
|
||||||
appContainer.resolve(ModuleRegistrationName.AUTH)
|
appContainer.resolve(ModuleRegistrationName.AUTH),
|
||||||
|
jwt_secret
|
||||||
)
|
)
|
||||||
|
|
||||||
const otherCustomer = await customerModuleService.create({
|
const otherCustomer = await customerModuleService.create({
|
||||||
first_name: "Jane",
|
first_name: "Jane",
|
||||||
last_name: "Doe",
|
last_name: "Doe",
|
||||||
})
|
})
|
||||||
|
|
||||||
const address = await customerModuleService.addAddresses({
|
const address = await customerModuleService.addAddresses({
|
||||||
customer_id: otherCustomer.id,
|
customer_id: otherCustomer.id,
|
||||||
first_name: "John",
|
first_name: "John",
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import { ICustomerModuleService, IAuthModuleService } from "@medusajs/types"
|
import { IAuthModuleService, ICustomerModuleService } from "@medusajs/types"
|
||||||
|
|
||||||
|
import jwt from "jsonwebtoken"
|
||||||
|
|
||||||
export const createAuthenticatedCustomer = async (
|
export const createAuthenticatedCustomer = async (
|
||||||
customerModuleService: ICustomerModuleService,
|
customerModuleService: ICustomerModuleService,
|
||||||
authService: IAuthModuleService
|
authService: IAuthModuleService,
|
||||||
|
jwtSecret: string
|
||||||
) => {
|
) => {
|
||||||
const customer = await customerModuleService.create({
|
const customer = await customerModuleService.create({
|
||||||
first_name: "John",
|
first_name: "John",
|
||||||
@@ -12,12 +15,12 @@ export const createAuthenticatedCustomer = async (
|
|||||||
|
|
||||||
const authUser = await authService.createAuthUser({
|
const authUser = await authService.createAuthUser({
|
||||||
entity_id: "store_user",
|
entity_id: "store_user",
|
||||||
provider_id: "test",
|
provider: "emailpass",
|
||||||
scope: "store",
|
scope: "store",
|
||||||
app_metadata: { customer_id: customer.id },
|
app_metadata: { customer_id: customer.id },
|
||||||
})
|
})
|
||||||
|
|
||||||
const jwt = await authService.generateJwtToken(authUser.id, "store")
|
const token = jwt.sign(authUser, jwtSecret)
|
||||||
|
|
||||||
return { customer, authUser, jwt }
|
return { customer, authUser, jwt: token }
|
||||||
}
|
}
|
||||||
@@ -46,9 +46,6 @@ module.exports = {
|
|||||||
scope: "internal",
|
scope: "internal",
|
||||||
resources: "shared",
|
resources: "shared",
|
||||||
resolve: "@medusajs/auth",
|
resolve: "@medusajs/auth",
|
||||||
options: {
|
|
||||||
jwt_secret: "test",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
[Modules.STOCK_LOCATION]: {
|
[Modules.STOCK_LOCATION]: {
|
||||||
scope: "internal",
|
scope: "internal",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { AbstractAuthModuleProvider, MedusaError } from "@medusajs/utils"
|
import { AbstractAuthModuleProvider, MedusaError } from "@medusajs/utils"
|
||||||
import {
|
import {
|
||||||
|
AuthProviderScope,
|
||||||
AuthenticationInput,
|
AuthenticationInput,
|
||||||
AuthenticationResponse,
|
AuthenticationResponse,
|
||||||
AuthProviderScope,
|
|
||||||
ModulesSdkTypes,
|
ModulesSdkTypes,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import { AuthUserService } from "@services"
|
import { AuthUserService } from "@services"
|
||||||
@@ -82,9 +82,9 @@ class GoogleProvider extends AbstractAuthModuleProvider {
|
|||||||
|
|
||||||
// abstractable
|
// abstractable
|
||||||
async verify_(refreshToken: string, scope: string) {
|
async verify_(refreshToken: string, scope: string) {
|
||||||
const jwtData = (await jwt.decode(refreshToken, {
|
const jwtData = jwt.decode(refreshToken, {
|
||||||
complete: true,
|
complete: true,
|
||||||
})) as JwtPayload
|
}) as JwtPayload
|
||||||
const entity_id = jwtData.payload.email
|
const entity_id = jwtData.payload.email
|
||||||
|
|
||||||
let authUser
|
let authUser
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import jwt from "jsonwebtoken"
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AuthenticationInput,
|
AuthenticationInput,
|
||||||
AuthenticationResponse,
|
AuthenticationResponse,
|
||||||
@@ -11,7 +9,6 @@ import {
|
|||||||
CreateAuthUserDTO,
|
CreateAuthUserDTO,
|
||||||
DAL,
|
DAL,
|
||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
JWTGenerationOptions,
|
|
||||||
ModuleJoinerConfig,
|
ModuleJoinerConfig,
|
||||||
ModulesSdkTypes,
|
ModulesSdkTypes,
|
||||||
UpdateAuthUserDTO,
|
UpdateAuthUserDTO,
|
||||||
@@ -31,15 +28,6 @@ import {
|
|||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { ServiceTypes } from "@types"
|
import { ServiceTypes } from "@types"
|
||||||
|
|
||||||
type AuthModuleOptions = {
|
|
||||||
jwt_secret: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthJWTPayload = {
|
|
||||||
id: string
|
|
||||||
scope: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
baseRepository: DAL.RepositoryService
|
baseRepository: DAL.RepositoryService
|
||||||
authUserService: ModulesSdkTypes.InternalModuleService<any>
|
authUserService: ModulesSdkTypes.InternalModuleService<any>
|
||||||
@@ -68,7 +56,6 @@ export default class AuthModuleService<
|
|||||||
protected baseRepository_: DAL.RepositoryService
|
protected baseRepository_: DAL.RepositoryService
|
||||||
protected authUserService_: ModulesSdkTypes.InternalModuleService<TAuthUser>
|
protected authUserService_: ModulesSdkTypes.InternalModuleService<TAuthUser>
|
||||||
protected authProviderService_: ModulesSdkTypes.InternalModuleService<TAuthProvider>
|
protected authProviderService_: ModulesSdkTypes.InternalModuleService<TAuthProvider>
|
||||||
protected options_: AuthModuleOptions
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{
|
{
|
||||||
@@ -76,7 +63,6 @@ export default class AuthModuleService<
|
|||||||
authProviderService,
|
authProviderService,
|
||||||
baseRepository,
|
baseRepository,
|
||||||
}: InjectedDependencies,
|
}: InjectedDependencies,
|
||||||
options: AuthModuleOptions,
|
|
||||||
protected readonly moduleDeclaration: InternalModuleDeclaration
|
protected readonly moduleDeclaration: InternalModuleDeclaration
|
||||||
) {
|
) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -85,53 +71,12 @@ export default class AuthModuleService<
|
|||||||
this.baseRepository_ = baseRepository
|
this.baseRepository_ = baseRepository
|
||||||
this.authUserService_ = authUserService
|
this.authUserService_ = authUserService
|
||||||
this.authProviderService_ = authProviderService
|
this.authProviderService_ = authProviderService
|
||||||
this.options_ = options
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__joinerConfig(): ModuleJoinerConfig {
|
__joinerConfig(): ModuleJoinerConfig {
|
||||||
return joinerConfig
|
return joinerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
async generateJwtToken(
|
|
||||||
authUserId: string,
|
|
||||||
scope: string,
|
|
||||||
options: JWTGenerationOptions = {}
|
|
||||||
): Promise<string> {
|
|
||||||
const authUser = await this.authUserService_.retrieve(authUserId)
|
|
||||||
return jwt.sign({ id: authUser.id, scope }, this.options_.jwt_secret, {
|
|
||||||
expiresIn: options.expiresIn || "1d",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async retrieveAuthUserFromJwtToken(
|
|
||||||
token: string,
|
|
||||||
scope: string
|
|
||||||
): Promise<AuthUserDTO> {
|
|
||||||
let decoded: AuthJWTPayload
|
|
||||||
try {
|
|
||||||
const verifiedToken = jwt.verify(token, this.options_.jwt_secret)
|
|
||||||
decoded = verifiedToken as AuthJWTPayload
|
|
||||||
} catch (err) {
|
|
||||||
throw new MedusaError(
|
|
||||||
MedusaError.Types.UNAUTHORIZED,
|
|
||||||
"The provided JWT token is invalid"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decoded.scope !== scope) {
|
|
||||||
throw new MedusaError(
|
|
||||||
MedusaError.Types.UNAUTHORIZED,
|
|
||||||
"The provided JWT token is invalid"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const authUser = await this.authUserService_.retrieve(decoded.id)
|
|
||||||
return await this.baseRepository_.serialize<AuthTypes.AuthUserDTO>(
|
|
||||||
authUser,
|
|
||||||
{ populate: true }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
async createAuthProvider(
|
async createAuthProvider(
|
||||||
data: CreateAuthProviderDTO[],
|
data: CreateAuthProviderDTO[],
|
||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
|
import jwt from "jsonwebtoken"
|
||||||
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
|
||||||
|
|
||||||
import { MedusaError } from "@medusajs/utils"
|
import { MedusaError } from "@medusajs/utils"
|
||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
||||||
|
|
||||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
const { scope, authProvider } = req.params
|
const { scope, authProvider } = req.params
|
||||||
@@ -29,10 +29,9 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
req.session.auth_user = authUser
|
const { jwt_secret } = req.scope.resolve("configModule").projectConfig
|
||||||
req.session.scope = authUser.scope
|
const token = jwt.sign(authUser, jwt_secret)
|
||||||
|
return res.status(200).json({ token })
|
||||||
return res.status(200).json({ authUser })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import jwt from "jsonwebtoken"
|
||||||
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
|
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
|
||||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
|
||||||
|
|
||||||
import { MedusaError } from "@medusajs/utils"
|
import { MedusaError } from "@medusajs/utils"
|
||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||||
|
|
||||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
const { scope, authProvider } = req.params
|
const { scope, authProvider } = req.params
|
||||||
@@ -29,10 +29,11 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
req.session.auth_user = authUser
|
const { jwt_secret } = req.scope.resolve("configModule").projectConfig
|
||||||
req.session.scope = authUser.scope
|
|
||||||
|
|
||||||
return res.status(200).json({ authUser })
|
const token = jwt.sign(authUser, jwt_secret)
|
||||||
|
|
||||||
|
return res.status(200).json({ token })
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { MiddlewareRoute } from "../../types/middlewares"
|
||||||
|
import { authenticate } from "../../utils/authenticate-middleware"
|
||||||
|
|
||||||
|
export const authRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/auth/session",
|
||||||
|
middlewares: [authenticate(/.*/, "bearer")],
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||||
|
|
||||||
|
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
req.session.auth_user = req.auth_user
|
||||||
|
|
||||||
|
res.status(200).json({ user: req.auth_user })
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
|
|||||||
import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares"
|
import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares"
|
||||||
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
||||||
import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
|
import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
|
||||||
|
import { authRoutesMiddlewares } from "./auth/middlewares"
|
||||||
|
|
||||||
export const config: MiddlewaresConfig = {
|
export const config: MiddlewaresConfig = {
|
||||||
routes: [
|
routes: [
|
||||||
@@ -14,5 +15,6 @@ export const config: MiddlewaresConfig = {
|
|||||||
...adminCampaignRoutesMiddlewares,
|
...adminCampaignRoutesMiddlewares,
|
||||||
...storeCustomerRoutesMiddlewares,
|
...storeCustomerRoutesMiddlewares,
|
||||||
...storeCartRoutesMiddlewares,
|
...storeCartRoutesMiddlewares,
|
||||||
|
...authRoutesMiddlewares,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@@ -228,9 +228,11 @@ class InviteService extends TransactionBaseService {
|
|||||||
|
|
||||||
verifyToken(token): JwtPayload | string {
|
verifyToken(token): JwtPayload | string {
|
||||||
const { jwt_secret } = this.configModule_.projectConfig
|
const { jwt_secret } = this.configModule_.projectConfig
|
||||||
|
|
||||||
if (jwt_secret) {
|
if (jwt_secret) {
|
||||||
return jwt.verify(token, jwt_secret)
|
return jwt.verify(token, jwt_secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
MedusaError.Types.INVALID_DATA,
|
MedusaError.Types.INVALID_DATA,
|
||||||
"Please configure jwt_secret"
|
"Please configure jwt_secret"
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { Customer, User } from "../models"
|
import type { Customer, User } from "../models"
|
||||||
import type { NextFunction, Request, Response } from "express"
|
import type { NextFunction, Request, Response } from "express"
|
||||||
|
|
||||||
import { AuthUserDTO } from "@medusajs/types"
|
|
||||||
import type { MedusaContainer } from "./global"
|
import type { MedusaContainer } from "./global"
|
||||||
|
|
||||||
export interface MedusaRequest extends Request {
|
export interface MedusaRequest extends Request {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { AuthUserDTO, IAuthModuleService } from "@medusajs/types"
|
|
||||||
import { MedusaRequest, MedusaResponse } from "../types/routing"
|
import { MedusaRequest, MedusaResponse } from "../types/routing"
|
||||||
import { NextFunction, RequestHandler } from "express"
|
import { NextFunction, RequestHandler } from "express"
|
||||||
|
import jwt, { JwtPayload } from "jsonwebtoken"
|
||||||
|
|
||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { AuthUserDTO } from "@medusajs/types"
|
||||||
|
import { stringEqualsOrRegexMatch } from "@medusajs/utils"
|
||||||
|
|
||||||
const SESSION_AUTH = "session"
|
const SESSION_AUTH = "session"
|
||||||
const BEARER_AUTH = "bearer"
|
const BEARER_AUTH = "bearer"
|
||||||
@@ -15,7 +16,7 @@ type MedusaSession = {
|
|||||||
type AuthType = "session" | "bearer"
|
type AuthType = "session" | "bearer"
|
||||||
|
|
||||||
export const authenticate = (
|
export const authenticate = (
|
||||||
authScope: string,
|
authScope: string | RegExp,
|
||||||
authType: AuthType | AuthType[],
|
authType: AuthType | AuthType[],
|
||||||
options: { allowUnauthenticated?: boolean } = {}
|
options: { allowUnauthenticated?: boolean } = {}
|
||||||
): RequestHandler => {
|
): RequestHandler => {
|
||||||
@@ -25,22 +26,23 @@ export const authenticate = (
|
|||||||
next: NextFunction
|
next: NextFunction
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const authTypes = Array.isArray(authType) ? authType : [authType]
|
const authTypes = Array.isArray(authType) ? authType : [authType]
|
||||||
const authModule = req.scope.resolve<IAuthModuleService>(
|
|
||||||
ModuleRegistrationName.AUTH
|
|
||||||
)
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const session: MedusaSession = req.session || {}
|
const session: MedusaSession = req.session || {}
|
||||||
|
|
||||||
let authUser: AuthUserDTO | null = null
|
let authUser: AuthUserDTO | null = null
|
||||||
if (authTypes.includes(SESSION_AUTH)) {
|
if (authTypes.includes(SESSION_AUTH)) {
|
||||||
if (session.auth_user && session.scope === authScope) {
|
if (
|
||||||
|
session.auth_user &&
|
||||||
|
stringEqualsOrRegexMatch(authScope, session.auth_user.scope)
|
||||||
|
) {
|
||||||
authUser = session.auth_user
|
authUser = session.auth_user
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!authUser && authTypes.includes(BEARER_AUTH)) {
|
if (!authUser && authTypes.includes(BEARER_AUTH)) {
|
||||||
const authHeader = req.headers.authorization
|
const authHeader = req.headers.authorization
|
||||||
|
|
||||||
if (authHeader) {
|
if (authHeader) {
|
||||||
const re = /(\S+)\s+(\S+)/
|
const re = /(\S+)\s+(\S+)/
|
||||||
const matches = authHeader.match(re)
|
const matches = authHeader.match(re)
|
||||||
@@ -49,10 +51,17 @@ export const authenticate = (
|
|||||||
if (matches) {
|
if (matches) {
|
||||||
const tokenType = matches[1]
|
const tokenType = matches[1]
|
||||||
const token = matches[2]
|
const token = matches[2]
|
||||||
if (tokenType.toLowerCase() === "bearer") {
|
if (tokenType.toLowerCase() === BEARER_AUTH) {
|
||||||
authUser = await authModule
|
// get config jwt secret
|
||||||
.retrieveAuthUserFromJwtToken(token, authScope)
|
// verify token and set authUser
|
||||||
.catch(() => null)
|
const { jwt_secret } =
|
||||||
|
req.scope.resolve("configModule").projectConfig
|
||||||
|
|
||||||
|
const verified = jwt.verify(token, jwt_secret) as JwtPayload
|
||||||
|
|
||||||
|
if (stringEqualsOrRegexMatch(authScope, verified.scope)) {
|
||||||
|
authUser = verified as AuthUserDTO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +71,7 @@ export const authenticate = (
|
|||||||
req.auth_user = {
|
req.auth_user = {
|
||||||
id: authUser.id,
|
id: authUser.id,
|
||||||
app_metadata: authUser.app_metadata,
|
app_metadata: authUser.app_metadata,
|
||||||
scope: authScope,
|
scope: authUser.scope,
|
||||||
}
|
}
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,16 +76,6 @@ export interface IAuthModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<AuthUserDTO>
|
): Promise<AuthUserDTO>
|
||||||
|
|
||||||
generateJwtToken(
|
|
||||||
authUserId: string,
|
|
||||||
scope: string,
|
|
||||||
options?: JWTGenerationOptions
|
|
||||||
): Promise<string>
|
|
||||||
retrieveAuthUserFromJwtToken(
|
|
||||||
token: string,
|
|
||||||
scope: string
|
|
||||||
): Promise<AuthUserDTO>
|
|
||||||
|
|
||||||
listAuthUsers(
|
listAuthUsers(
|
||||||
filters?: FilterableAuthProviderProps,
|
filters?: FilterableAuthProviderProps,
|
||||||
config?: FindConfig<AuthUserDTO>,
|
config?: FindConfig<AuthUserDTO>,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export * from "./remove-nullisih"
|
|||||||
export * from "./selector-constraints-to-string"
|
export * from "./selector-constraints-to-string"
|
||||||
export * from "./set-metadata"
|
export * from "./set-metadata"
|
||||||
export * from "./simple-hash"
|
export * from "./simple-hash"
|
||||||
|
export * from "./string-or-regex-equals"
|
||||||
export * from "./string-to-select-relation-object"
|
export * from "./string-to-select-relation-object"
|
||||||
export * from "./stringify-circular"
|
export * from "./stringify-circular"
|
||||||
export * from "./to-camel-case"
|
export * from "./to-camel-case"
|
||||||
@@ -42,4 +43,3 @@ export * from "./to-pascal-case"
|
|||||||
export * from "./transaction"
|
export * from "./transaction"
|
||||||
export * from "./upper-case-first"
|
export * from "./upper-case-first"
|
||||||
export * from "./wrap-handler"
|
export * from "./wrap-handler"
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export const stringEqualsOrRegexMatch = (
|
||||||
|
stringOrRegex: string | RegExp,
|
||||||
|
testString: string
|
||||||
|
) => {
|
||||||
|
if (stringOrRegex instanceof RegExp) {
|
||||||
|
return stringOrRegex.test(testString)
|
||||||
|
}
|
||||||
|
return stringOrRegex === testString
|
||||||
|
}
|
||||||
Reference in new issue
Block a user