Feat(auth): Remove auth provider entity (#6314)

**What**
- remove auth provider entity

**Why**
- The auth provider entity was not really used anywhere

**How**
- Keeping loader behavior as is but removing the 

Co-authored-by: Sebastian Rindom <7554214+srindom@users.noreply.github.com>
This commit is contained in:
Philip Korsholm
2024-02-06 15:54:34 +08:00
committed by GitHub
parent b2eaac8cb1
commit 882aa549bd
37 changed files with 179 additions and 1223 deletions

View File

@@ -0,0 +1,5 @@
---
"@medusajs/utils": patch
---
feat(utils): return array or single entity based on input for modules created by internal module service factory

View File

@@ -40,12 +40,7 @@ describe("POST /store/customers/me/addresses", () => {
})
it("should create a customer address", async () => {
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const { customer, jwt } = await createAuthenticatedCustomer(
customerModuleService,
appContainer.resolve(ModuleRegistrationName.AUTH),
jwt_secret
)
const { customer, jwt } = await createAuthenticatedCustomer(appContainer)
const api = useApi() as any
const response = await api.post(

View File

@@ -49,7 +49,7 @@ describe("POST /store/customers", () => {
ModuleRegistrationName.AUTH
)
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const authUser = await authService.createAuthUser({
const authUser = await authService.create({
entity_id: "store_user",
provider: "emailpass",
scope: "store",

View File

@@ -10,6 +10,8 @@ import { useApi } from "../../../../environment-helpers/use-api"
const env = { MEDUSA_FF_MEDUSA_V2: true }
jest.setTimeout(50000)
describe("DELETE /store/customers/me/addresses/:address_id", () => {
let dbConnection
let appContainer
@@ -26,14 +28,6 @@ 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 () => {
const db = useDb()
await db.shutdown()
@@ -46,12 +40,7 @@ describe("DELETE /store/customers/me/addresses/:address_id", () => {
})
it("should delete a customer address", async () => {
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const { customer, jwt } = await createAuthenticatedCustomer(
customerModuleService,
appContainer.resolve(ModuleRegistrationName.AUTH),
jwt_secret
)
const { customer, jwt } = await createAuthenticatedCustomer(appContainer)
const address = await customerModuleService.addAddresses({
customer_id: customer.id,
@@ -76,12 +65,7 @@ describe("DELETE /store/customers/me/addresses/:address_id", () => {
})
it("should fail to delete another customer's address", async () => {
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const { jwt } = await createAuthenticatedCustomer(
customerModuleService,
appContainer.resolve(ModuleRegistrationName.AUTH),
jwt_secret
)
const { jwt } = await createAuthenticatedCustomer(appContainer)
const otherCustomer = await customerModuleService.create({
first_name: "Jane",

View File

@@ -3,7 +3,6 @@ import { initDb, useDb } from "../../../../environment-helpers/use-db"
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 { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
@@ -41,12 +40,7 @@ describe("GET /store/customers", () => {
})
it("should retrieve auth user's customer", async () => {
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const { customer, jwt } = await createAuthenticatedCustomer(
customerModuleService,
appContainer.resolve(ModuleRegistrationName.AUTH),
jwt_secret
)
const { customer, jwt } = await createAuthenticatedCustomer(appContainer)
const api = useApi() as any
const response = await api.get(`/store/customers/me`, {

View File

@@ -44,12 +44,7 @@ describe("GET /store/customers/me/addresses", () => {
})
it("should get all customer addresses and its count", async () => {
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const { customer, jwt } = await createAuthenticatedCustomer(
customerModuleService,
appContainer.resolve(ModuleRegistrationName.AUTH),
jwt_secret
)
const { customer, jwt } = await createAuthenticatedCustomer(appContainer)
await customerModuleService.addAddresses([
{

View File

@@ -26,14 +26,6 @@ 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 () => {
const db = useDb()
await db.shutdown()
@@ -46,13 +38,7 @@ describe("POST /store/customers/:id/addresses/:address_id", () => {
})
it("should update a customer address", async () => {
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const { customer, jwt } = await createAuthenticatedCustomer(
customerModuleService,
appContainer.resolve(ModuleRegistrationName.AUTH),
jwt_secret
)
const { customer, jwt } = await createAuthenticatedCustomer(appContainer)
const address = await customerModuleService.addAddresses({
customer_id: customer.id,
@@ -81,13 +67,7 @@ describe("POST /store/customers/:id/addresses/:address_id", () => {
})
it("should fail to update another customer's address", async () => {
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const { jwt } = await createAuthenticatedCustomer(
customerModuleService,
appContainer.resolve(ModuleRegistrationName.AUTH),
jwt_secret
)
const { jwt } = await createAuthenticatedCustomer(appContainer)
const otherCustomer = await customerModuleService.create({
first_name: "Jane",

View File

@@ -1,26 +1,33 @@
import { IAuthModuleService, ICustomerModuleService } from "@medusajs/types"
import { CreateCustomerDTO, MedusaContainer } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import jwt from "jsonwebtoken"
export const createAuthenticatedCustomer = async (
customerModuleService: ICustomerModuleService,
authService: IAuthModuleService,
jwtSecret: string
appContainer: MedusaContainer,
customerData: Partial<CreateCustomerDTO> = {}
) => {
const { jwt_secret } = appContainer.resolve("configModule").projectConfig
const authService = appContainer.resolve(ModuleRegistrationName.AUTH)
const customerModuleService = appContainer.resolve(
ModuleRegistrationName.CUSTOMER
)
const customer = await customerModuleService.create({
first_name: "John",
last_name: "Doe",
email: "john@me.com",
...customerData,
})
const authUser = await authService.createAuthUser({
const authUser = await authService.create({
entity_id: "store_user",
provider: "emailpass",
scope: "store",
app_metadata: { customer_id: customer.id },
})
const token = jwt.sign(authUser, jwtSecret)
const token = jwt.sign(authUser, jwt_secret)
return { customer, authUser, jwt: token }
}

View File

@@ -1,41 +0,0 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { AuthProvider } from "@models"
export async function createAuthProviders(
manager: SqlEntityManager,
providerData: any[] = [
{
provider: "manual",
name: "manual",
is_active: true,
},
{
provider: "disabled",
name: "disabled",
},
{
provider: "store",
name: "store",
domain: "store",
is_active: true,
},
{
provider: "admin",
name: "admin",
domain: "admin",
is_active: true,
},
]
): Promise<AuthProvider[]> {
const authProviders: AuthProvider[] = []
for (const provider of providerData) {
const authProvider = manager.create(AuthProvider, provider)
authProviders.push(authProvider)
}
await manager.persistAndFlush(authProviders)
return authProviders
}

View File

@@ -1,271 +0,0 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { MikroOrmWrapper } from "../../../utils"
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix"
import ContainerLoader from "../../../../src/loaders/container"
import { ModulesSdkTypes } from "@medusajs/types"
jest.setTimeout(30000)
describe("AuthProvider Service", () => {
let service: ModulesSdkTypes.InternalModuleService<any>
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = await MikroOrmWrapper.forkManager()
testManager = await MikroOrmWrapper.forkManager()
const container = createMedusaContainer()
container.register("manager", asValue(repositoryManager))
await ContainerLoader({ container })
service = container.resolve("authProviderService")
await createAuthProviders(testManager)
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("list", () => {
it("should list AuthProviders", async () => {
const authProviders = await service.list()
const serialized = JSON.parse(JSON.stringify(authProviders))
expect(serialized).toEqual([
expect.objectContaining({
provider: "manual",
}),
expect.objectContaining({
provider: "disabled",
}),
expect.objectContaining({
provider: "store",
}),
expect.objectContaining({
provider: "admin",
}),
])
})
it("should list authProviders by provider id", async () => {
const authProviders = await service.list({
provider: ["manual"],
})
expect(authProviders).toEqual([
expect.objectContaining({
provider: "manual",
}),
])
})
it("should list active authProviders", async () => {
const authProviders = await service.list({
is_active: true,
})
const serialized = JSON.parse(JSON.stringify(authProviders))
expect(serialized).toEqual([
expect.objectContaining({
provider: "manual",
}),
expect.objectContaining({
provider: "store",
}),
expect.objectContaining({
provider: "admin",
}),
])
})
})
describe("listAndCount", () => {
it("should list AuthProviders", async () => {
const [authProviders, count] = await service.listAndCount()
const serialized = JSON.parse(JSON.stringify(authProviders))
expect(count).toEqual(4)
expect(serialized).toEqual([
expect.objectContaining({
provider: "manual",
}),
expect.objectContaining({
provider: "disabled",
}),
expect.objectContaining({
provider: "store",
}),
expect.objectContaining({
provider: "admin",
}),
])
})
it("should listAndCount authProviders by provider", async () => {
const [authProviders, count] = await service.listAndCount({
provider: ["manual"],
})
expect(count).toEqual(1)
expect(authProviders).toEqual([
expect.objectContaining({
provider: "manual",
}),
])
})
it("should listAndCount active authProviders", async () => {
const [authProviders, count] = await service.listAndCount({
is_active: true,
})
const serialized = JSON.parse(JSON.stringify(authProviders))
expect(count).toEqual(3)
expect(serialized).toEqual([
expect.objectContaining({
provider: "manual",
}),
expect.objectContaining({
provider: "store",
}),
expect.objectContaining({
provider: "admin",
}),
])
})
})
describe("retrieve", () => {
const provider = "manual"
it("should return an authProvider for the given provider", async () => {
const authProvider = await service.retrieve(provider)
expect(authProvider).toEqual(
expect.objectContaining({
provider,
})
)
})
it("should throw an error when an authProvider with the given provider does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"AuthProvider with provider: does-not-exist was not found"
)
})
it("should throw an error when a provider is not provided", async () => {
let error
try {
await service.retrieve(undefined as unknown as string)
} catch (e) {
error = e
}
expect(error.message).toEqual("authProvider - provider must be defined")
})
it("should return authProvider based on config select param", async () => {
const authProvider = await service.retrieve(provider, {
select: ["provider"],
})
const serialized = JSON.parse(JSON.stringify(authProvider))
expect(serialized).toEqual({
provider,
})
})
})
describe("delete", () => {
const provider = "manual"
it("should delete the authProviders given a provider successfully", async () => {
await service.delete([provider])
const authProviders = await service.list({
provider: [provider],
})
expect(authProviders).toHaveLength(0)
})
})
describe("update", () => {
const provider = "manual"
it("should throw an error when a id does not exist", async () => {
let error
try {
await service.update([
{
provider: "does-not-exist",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'AuthProvider with provider "does-not-exist" not found'
)
})
it("should update authProvider", async () => {
await service.update([
{
provider: "manual",
name: "test",
},
])
const [provider] = await service.list({ provider: ["manual"] })
expect(provider).toEqual(
expect.objectContaining({
name: "test",
})
)
})
})
describe("create", () => {
it("should create a authProvider successfully", async () => {
await service.create([
{
provider: "test",
name: "test provider",
},
])
const [authProvider] = await service.list({
provider: ["test"],
})
expect(authProvider).toEqual(
expect.objectContaining({
provider: "test",
})
)
})
})
})

View File

@@ -3,7 +3,6 @@ import ContainerLoader from "../../../../src/loaders/container"
import { MikroOrmWrapper } from "../../../utils"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { asValue } from "awilix"
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
import { createAuthUsers } from "../../../__fixtures__/auth-user"
import { createMedusaContainer } from "@medusajs/utils"
@@ -26,7 +25,6 @@ describe("AuthUser Service", () => {
service = container.resolve("authUserService")
await createAuthProviders(testManager)
await createAuthUsers(testManager)
})
@@ -66,7 +64,7 @@ describe("AuthUser Service", () => {
it("should list authUsers by provider_id", async () => {
const authUsers = await service.list({
provider_id: "manual",
provider: "manual",
})
const serialized = JSON.parse(JSON.stringify(authUsers))
@@ -103,7 +101,7 @@ describe("AuthUser Service", () => {
it("should listAndCount authUsers by provider_id", async () => {
const [authUsers, count] = await service.listAndCount({
provider_id: "manual",
provider: "manual",
})
expect(count).toEqual(2)
@@ -227,7 +225,7 @@ describe("AuthUser Service", () => {
await service.create([
{
id: "test",
provider_id: "manual",
provider: "manual",
entity_id: "test",
scope: "store",
},

View File

@@ -1,274 +0,0 @@
import { Modules } from "@medusajs/modules-sdk"
import { IAuthModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { initModules } from "medusa-test-utils"
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
import { createAuthUsers } from "../../../__fixtures__/auth-user"
import { MikroOrmWrapper } from "../../../utils"
import { getInitModuleConfig } from "../../../utils/get-init-module-config"
jest.setTimeout(30000)
describe("AuthModuleService - AuthProvider", () => {
let service: IAuthModuleService
let testManager: SqlEntityManager
let shutdownFunc: () => Promise<void>
beforeAll(async () => {
const initModulesConfig = getInitModuleConfig()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
service = medusaApp.modules[Modules.AUTH]
shutdownFunc = shutdown
})
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
testManager = MikroOrmWrapper.forkManager()
await createAuthProviders(testManager)
await createAuthUsers(testManager)
})
afterAll(async () => {
await shutdownFunc()
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("listAuthProviders", () => {
it("should list AuthProviders", async () => {
const authProviders = await service.listAuthProviders()
expect(authProviders).toEqual(
expect.arrayContaining([
expect.objectContaining({
provider: "manual",
}),
expect.objectContaining({
provider: "disabled",
}),
expect.objectContaining({
provider: "store",
}),
expect.objectContaining({
provider: "admin",
}),
])
)
})
it("should list authProviders by id", async () => {
const authProviders = await service.listAuthProviders({
provider: ["manual"],
})
expect(authProviders).toEqual([
expect.objectContaining({
provider: "manual",
}),
])
})
it("should list active authProviders", async () => {
const authProviders = await service.listAuthProviders({
is_active: true,
})
expect(authProviders).toEqual([
expect.objectContaining({
provider: "manual",
}),
expect.objectContaining({
provider: "store",
}),
expect.objectContaining({
provider: "admin",
}),
])
})
})
describe("listAndCountAuthProviders", () => {
it("should list and count AuthProviders", async () => {
const [authProviders, count] = await service.listAndCountAuthProviders()
expect(count).toEqual(4)
expect(authProviders).toEqual([
expect.objectContaining({
provider: "manual",
}),
expect.objectContaining({
provider: "disabled",
}),
expect.objectContaining({
provider: "store",
}),
expect.objectContaining({
provider: "admin",
}),
])
})
it("should list and count authProviders by provider", async () => {
const [authProviders, count] = await service.listAndCountAuthProviders({
provider: ["manual"],
})
expect(count).toEqual(1)
expect(authProviders).toEqual([
expect.objectContaining({
provider: "manual",
}),
])
})
it("should list and count active authProviders", async () => {
const [authProviders, count] = await service.listAndCountAuthProviders({
is_active: true,
})
expect(count).toEqual(3)
expect(authProviders).toEqual([
expect.objectContaining({
provider: "manual",
}),
expect.objectContaining({
provider: "store",
}),
expect.objectContaining({
provider: "admin",
}),
])
})
})
describe("retrieveAuthProvider", () => {
const provider = "manual"
it("should return an authProvider for the given provider", async () => {
const authProvider = await service.retrieveAuthProvider(provider)
expect(authProvider).toEqual(
expect.objectContaining({
provider,
})
)
})
it("should return authProvider based on config select param", async () => {
const authProvider = await service.retrieveAuthProvider(provider, {
select: ["provider"],
})
expect(authProvider).toEqual({
provider,
})
})
it("should throw an error when an authProvider with the given provider does not exist", async () => {
let error
try {
await service.retrieveAuthProvider("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"AuthProvider with provider: does-not-exist was not found"
)
})
it("should throw an error when a provider is not provided", async () => {
let error
try {
await service.retrieveAuthProvider(undefined as unknown as string)
} catch (e) {
error = e
}
expect(error.message).toEqual("authProvider - provider must be defined")
})
})
describe("deleteAuthProvider", () => {
const provider = "manual"
it("should delete the authProviders given a provider successfully", async () => {
await service.deleteAuthProviders([provider])
const authProviders = await service.listAuthProviders({
provider: [provider],
})
expect(authProviders).toHaveLength(0)
})
})
describe("updateAuthProvider", () => {
const provider = "manual"
it("should throw an error when a id does not exist", async () => {
let error
try {
await service.updateAuthProvider([
{
provider: "does-not-exist",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'AuthProvider with provider "does-not-exist" not found'
)
})
it("should update authProvider", async () => {
await service.updateAuthProvider([
{
provider: "manual",
name: "test",
},
])
const [provider] = await service.listAuthProviders({
provider: ["manual"],
})
expect(provider).toEqual(
expect.objectContaining({
name: "test",
})
)
})
})
describe("createAuthProvider", () => {
it("should create a authProvider successfully", async () => {
await service.createAuthProvider([
{
provider: "test",
name: "test provider",
},
])
const [authProvider] = await service.listAuthProviders({
provider: ["test"],
})
expect(authProvider).toEqual(
expect.objectContaining({
provider: "test",
})
)
})
})
})

View File

@@ -1,11 +1,10 @@
import { Modules } from "@medusajs/modules-sdk"
import { IAuthModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { initModules } from "medusa-test-utils"
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
import { createAuthUsers } from "../../../__fixtures__/auth-user"
import { MikroOrmWrapper } from "../../../utils"
import { Modules } from "@medusajs/modules-sdk"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { createAuthUsers } from "../../../__fixtures__/auth-user"
import { getInitModuleConfig } from "../../../utils/get-init-module-config"
import { initModules } from "medusa-test-utils"
jest.setTimeout(30000)
@@ -28,7 +27,6 @@ describe("AuthModuleService - AuthUser", () => {
await MikroOrmWrapper.setupDatabase()
testManager = MikroOrmWrapper.forkManager()
await createAuthProviders(testManager)
await createAuthUsers(testManager)
})
@@ -42,23 +40,23 @@ describe("AuthModuleService - AuthUser", () => {
describe("listAuthUsers", () => {
it("should list authUsers", async () => {
const authUsers = await service.listAuthUsers()
const authUsers = await service.list()
expect(authUsers).toEqual([
expect.objectContaining({
provider: { provider: "manual" },
provider: "manual",
}),
expect.objectContaining({
provider: { provider: "manual" },
provider: "manual",
}),
expect.objectContaining({
provider: { provider: "store" },
provider: "store",
}),
])
})
it("should list authUsers by id", async () => {
const authUsers = await service.listAuthUsers({
const authUsers = await service.list({
id: ["test-id"],
})
@@ -69,9 +67,9 @@ describe("AuthModuleService - AuthUser", () => {
])
})
it("should list authUsers by provider_id", async () => {
const authUsers = await service.listAuthUsers({
provider_id: "manual",
it("should list authUsers by provider", async () => {
const authUsers = await service.list({
provider: "manual",
})
expect(authUsers).toEqual([
@@ -87,25 +85,25 @@ describe("AuthModuleService - AuthUser", () => {
describe("listAndCountAuthUsers", () => {
it("should list and count authUsers", async () => {
const [authUsers, count] = await service.listAndCountAuthUsers()
const [authUsers, count] = await service.listAndCount()
expect(count).toEqual(3)
expect(authUsers).toEqual([
expect.objectContaining({
provider: { provider: "manual" },
provider: "manual",
}),
expect.objectContaining({
provider: { provider: "manual" },
provider: "manual",
}),
expect.objectContaining({
provider: { provider: "store" },
provider: "store",
}),
])
})
it("should listAndCount authUsers by provider_id", async () => {
const [authUsers, count] = await service.listAndCountAuthUsers({
provider_id: "manual",
const [authUsers, count] = await service.listAndCount({
provider: "manual",
})
expect(count).toEqual(2)
@@ -124,7 +122,7 @@ describe("AuthModuleService - AuthUser", () => {
const id = "test-id"
it("should return an authUser for the given id", async () => {
const authUser = await service.retrieveAuthUser(id)
const authUser = await service.retrieve(id)
expect(authUser).toEqual(
expect.objectContaining({
@@ -137,7 +135,7 @@ describe("AuthModuleService - AuthUser", () => {
let error
try {
await service.retrieveAuthUser("does-not-exist")
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
@@ -148,7 +146,7 @@ describe("AuthModuleService - AuthUser", () => {
})
it("should not return an authUser with password hash", async () => {
const authUser = await service.retrieveAuthUser("test-id-1")
const authUser = await service.retrieve("test-id-1")
expect(authUser).toEqual(
expect.objectContaining({
@@ -162,7 +160,7 @@ describe("AuthModuleService - AuthUser", () => {
let error
try {
await service.retrieveAuthUser(undefined as unknown as string)
await service.retrieve(undefined as unknown as string)
} catch (e) {
error = e
}
@@ -171,7 +169,7 @@ describe("AuthModuleService - AuthUser", () => {
})
it("should return authUser based on config select param", async () => {
const authUser = await service.retrieveAuthUser(id, {
const authUser = await service.retrieve(id, {
select: ["id"],
})
@@ -185,9 +183,9 @@ describe("AuthModuleService - AuthUser", () => {
const id = "test-id"
it("should delete the authUsers given an id successfully", async () => {
await service.deleteAuthUsers([id])
await service.delete([id])
const authUsers = await service.listAuthUsers({
const authUsers = await service.list({
id: [id],
})
@@ -202,7 +200,7 @@ describe("AuthModuleService - AuthUser", () => {
let error
try {
await service.updateAuthUser([
await service.update([
{
id: "does-not-exist",
},
@@ -217,14 +215,14 @@ describe("AuthModuleService - AuthUser", () => {
})
it("should update authUser", async () => {
await service.updateAuthUser([
await service.update([
{
id,
provider_metadata: { email: "test@email.com" },
},
])
const [authUser] = await service.listAuthUsers({ id: [id] })
const [authUser] = await service.list({ id: [id] })
expect(authUser).toEqual(
expect.objectContaining({
provider_metadata: { email: "test@email.com" },
@@ -235,16 +233,16 @@ describe("AuthModuleService - AuthUser", () => {
describe("createAuthUser", () => {
it("should create a authUser successfully", async () => {
await service.createAuthUser([
await service.create([
{
id: "test",
provider_id: "manual",
provider: "manual",
entity_id: "test",
scope: "store",
},
])
const [authUser, count] = await service.listAndCountAuthUsers({
const [authUser, count] = await service.listAndCount({
id: ["test"],
})

View File

@@ -1,10 +1,10 @@
import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { IAuthModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { initModules } from "medusa-test-utils"
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
import { MikroOrmWrapper } from "../../../utils"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { getInitModuleConfig } from "../../../utils/get-init-module-config"
import { initModules } from "medusa-test-utils"
jest.setTimeout(30000)
@@ -41,34 +41,8 @@ describe("AuthModuleService - AuthProvider", () => {
await shutdownFunc()
})
describe("listAuthProviders", () => {
it("should list default AuthProviders registered by loaders", async () => {
const authProviders = await service.listAuthProviders()
expect(authProviders).toEqual(
expect.arrayContaining([
expect.objectContaining({
provider: "emailpass",
name: "Email/Password Authentication",
}),
expect.objectContaining({
provider: "google",
name: "Google Authentication",
}),
])
)
})
})
describe("authenticate", () => {
it("authenticate validates that a provider is registered in container", async () => {
await createAuthProviders(testManager, [
{
provider: "notRegistered",
name: "test",
},
])
const { success, error } = await service.authenticate(
"notRegistered",
{} as any
@@ -76,7 +50,7 @@ describe("AuthModuleService - AuthProvider", () => {
expect(success).toBe(false)
expect(error).toEqual(
"AuthenticationProvider with for provider: notRegistered wasn't registered in the module. Have you configured your options correctly?"
"AuthenticationProvider: notRegistered wasn't registered in the module. Have you configured your options correctly?"
)
})

View File

@@ -4,14 +4,12 @@ import { IAuthModuleService } from "@medusajs/types"
import { MikroOrmWrapper } from "../../../utils"
import Scrypt from "scrypt-kdf"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
import { createAuthUsers } from "../../../__fixtures__/auth-user"
import { getInitModuleConfig } from "../../../utils/get-init-module-config"
import { initModules } from "medusa-test-utils"
jest.setTimeout(30000)
const seedDefaultData = async (testManager) => {
await createAuthProviders(testManager)
await createAuthUsers(testManager)
}
@@ -87,8 +85,6 @@ describe("AuthModuleService - AuthProvider", () => {
})
it("fails when no password is given", async () => {
const email = "test@test.com"
await seedDefaultData(testManager)
const res = await service.authenticate("emailpass", {

View File

@@ -4,71 +4,6 @@
],
"name": "public",
"tables": [
{
"columns": {
"provider": {
"name": "provider",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"name": {
"name": "name",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"scope": {
"name": "scope",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"config": {
"name": "config",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "json"
},
"is_active": {
"name": "is_active",
"type": "boolean",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"default": "false",
"mappedType": "boolean"
}
},
"name": "auth_provider",
"schema": "public",
"indexes": [
{
"keyName": "auth_provider_pkey",
"columnNames": [
"provider"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {}
},
{
"columns": {
"id": {
@@ -89,13 +24,13 @@
"nullable": false,
"mappedType": "text"
},
"provider_id": {
"name": "provider_id",
"provider": {
"name": "provider",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"nullable": false,
"mappedType": "text"
},
"scope": {
@@ -141,7 +76,7 @@
{
"keyName": "IDX_auth_user_provider_scope_entity_id",
"columnNames": [
"provider_id",
"provider",
"scope",
"entity_id"
],
@@ -160,20 +95,7 @@
}
],
"checks": [],
"foreignKeys": {
"auth_user_provider_id_foreign": {
"constraintName": "auth_user_provider_id_foreign",
"columnNames": [
"provider_id"
],
"localTableName": "public.auth_user",
"referencedColumnNames": [
"provider"
],
"referencedTableName": "public.auth_provider",
"deleteRule": "cascade"
}
}
"foreignKeys": {}
}
]
}

View File

@@ -1,22 +0,0 @@
import { Migration } from '@mikro-orm/migrations';
export class Migration20240201100135 extends Migration {
async up(): Promise<void> {
this.addSql('create table "auth_provider" ("provider" text not null, "name" text not null, "scope" text null, "config" jsonb null, "is_active" boolean not null default false, constraint "auth_provider_pkey" primary key ("provider"));');
this.addSql('create table "auth_user" ("id" text not null, "entity_id" text not null, "provider_id" text null, "scope" text not null, "user_metadata" jsonb null, "app_metadata" jsonb not null, "provider_metadata" jsonb null, constraint "auth_user_pkey" primary key ("id"));');
this.addSql('alter table "auth_user" add constraint "IDX_auth_user_provider_scope_entity_id" unique ("provider_id", "scope", "entity_id");');
this.addSql('alter table "auth_user" add constraint "auth_user_provider_id_foreign" foreign key ("provider_id") references "auth_provider" ("provider") on delete cascade;');
}
async down(): Promise<void> {
this.addSql('alter table "auth_user" drop constraint "auth_user_provider_id_foreign";');
this.addSql('drop table if exists "auth_provider" cascade;');
this.addSql('drop table if exists "auth_user" cascade;');
}
}

View File

@@ -0,0 +1,16 @@
import { Migration } from "@mikro-orm/migrations"
export class Migration20240205025924 extends Migration {
async up(): Promise<void> {
this.addSql(
'create table if not exists "auth_user" ("id" text not null, "entity_id" text not null, "provider" text not null, "scope" text not null, "user_metadata" jsonb null, "app_metadata" jsonb not null, "provider_metadata" jsonb null, constraint "auth_user_pkey" primary key ("id"));'
)
this.addSql(
'alter table "auth_user" add constraint "IDX_auth_user_provider_scope_entity_id" unique ("provider", "scope", "entity_id");'
)
}
async down(): Promise<void> {
this.addSql('drop table if exists "auth_user" cascade;')
}
}

View File

@@ -1,31 +0,0 @@
import {
Entity,
Enum,
OptionalProps,
PrimaryKey,
Property,
} from "@mikro-orm/core"
import { ProviderDomain } from "../types/repositories/auth-provider"
type OptionalFields = "domain" | "is_active" | "config"
@Entity()
export default class AuthProvider {
[OptionalProps]: OptionalFields
@PrimaryKey({ columnType: "text" })
provider!: string
@Property({ columnType: "text" })
name: string
@Property({ columnType: "text", nullable: true })
scope: string
@Property({ columnType: "jsonb", nullable: true })
config: Record<string, unknown> | null = null
@Property({ columnType: "boolean", default: false })
is_active = false
}

View File

@@ -11,7 +11,6 @@ import {
Unique,
} from "@mikro-orm/core"
import AuthProvider from "./auth-provider"
import { generateEntityId } from "@medusajs/utils"
type OptionalFields = "provider_metadata" | "app_metadata" | "user_metadata"
@@ -30,12 +29,8 @@ export default class AuthUser {
@Property({ columnType: "text" })
entity_id: string
@ManyToOne(() => AuthProvider, {
joinColumn: "provider",
fieldName: "provider_id",
cascade: [Cascade.REMOVE],
})
provider: AuthProvider
@Property({ columnType: "text" })
provider: string
@Property({ columnType: "text" })
scope: string

View File

@@ -1,2 +1 @@
export { default as AuthUser } from "./auth-user"
export { default as AuthProvider } from "./auth-provider"

View File

@@ -15,13 +15,16 @@ class EmailPasswordProvider extends AbstractAuthModuleProvider {
protected readonly authUserSerivce_: AuthUserService
constructor({ authUserService }: { authUserService: AuthUserService }) {
super(arguments[0])
super(arguments[0], {
provider: EmailPasswordProvider.PROVIDER,
displayName: EmailPasswordProvider.DISPLAY_NAME,
})
this.authUserSerivce_ = authUserService
}
private getHashConfig(scope: string) {
const scopeConfig = this.scopes_[scope].hashConfig as
private getHashConfig() {
const scopeConfig = this.scopeConfig_.hashConfig as
| Scrypt.ScryptParams
| undefined
@@ -58,16 +61,13 @@ class EmailPasswordProvider extends AbstractAuthModuleProvider {
)
} catch (error) {
if (error.type === MedusaError.Types.NOT_FOUND) {
const password_hash = await Scrypt.kdf(
password,
this.getHashConfig(userData.authScope)
)
const password_hash = await Scrypt.kdf(password, this.getHashConfig())
const [createdAuthUser] = await this.authUserSerivce_.create([
{
entity_id: email,
provider: EmailPasswordProvider.PROVIDER,
scope: userData.authScope,
scope: this.scope_,
provider_metadata: {
password: password_hash.toString("base64"),
},

View File

@@ -5,9 +5,9 @@ import {
AuthenticationResponse,
ModulesSdkTypes,
} from "@medusajs/types"
import { AuthUserService } from "@services"
import jwt, { JwtPayload } from "jsonwebtoken"
import { AuthUserService } from "@services"
import { AuthorizationCode } from "simple-oauth2"
import url from "url"
@@ -30,7 +30,10 @@ class GoogleProvider extends AbstractAuthModuleProvider {
protected readonly authProviderService_: ModulesSdkTypes.InternalModuleService<any>
constructor({ authUserService, authProviderService }: InjectedDependencies) {
super(arguments[0])
super(arguments[0], {
provider: GoogleProvider.PROVIDER,
displayName: GoogleProvider.DISPLAY_NAME,
})
this.authUserService_ = authUserService
this.authProviderService_ = authProviderService
@@ -77,11 +80,11 @@ class GoogleProvider extends AbstractAuthModuleProvider {
const code = req.query?.code ?? req.body?.code
return await this.validateCallbackToken(code, req.authScope, config)
return await this.validateCallbackToken(code, config)
}
// abstractable
async verify_(refreshToken: string, scope: string) {
async verify_(refreshToken: string) {
const jwtData = jwt.decode(refreshToken, {
complete: true,
}) as JwtPayload
@@ -101,7 +104,7 @@ class GoogleProvider extends AbstractAuthModuleProvider {
entity_id,
provider: GoogleProvider.PROVIDER,
user_metadata: jwtData!.payload,
scope,
scope: this.scope_,
},
])
authUser = createdAuthUser
@@ -116,7 +119,6 @@ class GoogleProvider extends AbstractAuthModuleProvider {
// abstractable
private async validateCallbackToken(
code: string,
scope: string,
{ clientID, callbackURL, clientSecret }: ProviderConfig
) {
const client = this.getAuthorizationCodeHandler({ clientID, clientSecret })
@@ -129,30 +131,28 @@ class GoogleProvider extends AbstractAuthModuleProvider {
try {
const accessToken = await client.getToken(tokenParams)
return await this.verify_(accessToken.token.id_token, scope)
return await this.verify_(accessToken.token.id_token)
} catch (error) {
return { success: false, error: error.message }
}
}
private getConfigFromScope(
config: AuthProviderScope & Partial<ProviderConfig>
): ProviderConfig {
const providerConfig: Partial<ProviderConfig> = { ...config }
private getConfigFromScope(): ProviderConfig {
const config: Partial<ProviderConfig> = { ...this.scopeConfig_ }
if (!providerConfig.clientID) {
if (!config.clientID) {
throw new Error("Google clientID is required")
}
if (!providerConfig.clientSecret) {
if (!config.clientSecret) {
throw new Error("Google clientSecret is required")
}
if (!providerConfig.callbackURL) {
if (!config.callbackURL) {
throw new Error("Google callbackUrl is required")
}
return providerConfig as ProviderConfig
return config as ProviderConfig
}
private originalURL(req: AuthenticationInput) {
@@ -168,11 +168,9 @@ class GoogleProvider extends AbstractAuthModuleProvider {
): Promise<ProviderConfig> {
await this.authProviderService_.retrieve(GoogleProvider.PROVIDER)
const scopeConfig = this.scopes_[req.authScope]
const config = this.getConfigFromScope()
const config = this.getConfigFromScope(scopeConfig)
const { callbackURL } = config
const callbackURL = config.callbackURL
const parsedCallbackUrl = !url.parse(callbackURL).protocol
? url.resolve(this.originalURL(req), callbackURL)

View File

@@ -1,11 +1,9 @@
import {
AuthenticationInput,
AuthenticationResponse,
AuthProviderDTO,
AuthTypes,
AuthUserDTO,
Context,
CreateAuthProviderDTO,
CreateAuthUserDTO,
DAL,
InternalModuleDeclaration,
@@ -14,7 +12,7 @@ import {
UpdateAuthUserDTO,
} from "@medusajs/types"
import { AuthProvider, AuthUser } from "@models"
import { AuthUser } from "@models"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
@@ -26,43 +24,29 @@ import {
MedusaError,
ModulesSdkUtils,
} from "@medusajs/utils"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
baseRepository: DAL.RepositoryService
authUserService: ModulesSdkTypes.InternalModuleService<any>
authProviderService: ModulesSdkTypes.InternalModuleService<any>
}
const generateMethodForModels = [AuthProvider, AuthUser]
const generateMethodForModels = [AuthUser]
export default class AuthModuleService<
TAuthUser extends AuthUser = AuthUser,
TAuthProvider extends AuthProvider = AuthProvider
>
export default class AuthModuleService<TAuthUser extends AuthUser = AuthUser>
extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies,
AuthTypes.AuthProviderDTO,
AuthTypes.AuthUserDTO,
{
AuthUser: { dto: AuthUserDTO }
AuthProvider: { dto: AuthProviderDTO }
}
>(AuthProvider, generateMethodForModels, entityNameToLinkableKeysMap)
>(AuthUser, generateMethodForModels, entityNameToLinkableKeysMap)
implements AuthTypes.IAuthModuleService
{
__hooks = {
onApplicationStart: async () => await this.createProvidersOnLoad(),
}
protected baseRepository_: DAL.RepositoryService
protected authUserService_: ModulesSdkTypes.InternalModuleService<TAuthUser>
protected authProviderService_: ModulesSdkTypes.InternalModuleService<TAuthProvider>
constructor(
{
authUserService,
authProviderService,
baseRepository,
}: InjectedDependencies,
{ authUserService, baseRepository }: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration
) {
// @ts-ignore
@@ -70,94 +54,25 @@ export default class AuthModuleService<
this.baseRepository_ = baseRepository
this.authUserService_ = authUserService
this.authProviderService_ = authProviderService
}
__joinerConfig(): ModuleJoinerConfig {
return joinerConfig
}
async createAuthProvider(
data: CreateAuthProviderDTO[],
sharedContext?: Context
): Promise<AuthProviderDTO[]>
async createAuthProvider(
data: CreateAuthProviderDTO,
sharedContext?: Context
): Promise<AuthProviderDTO>
@InjectManager("baseRepository_")
async createAuthProvider(
data: CreateAuthProviderDTO | CreateAuthProviderDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<AuthTypes.AuthProviderDTO | AuthTypes.AuthProviderDTO[]> {
const input = Array.isArray(data) ? data : [data]
const providers = await this.createAuthProviders_(input, sharedContext)
const serializedProviders = await this.baseRepository_.serialize<
AuthTypes.AuthProviderDTO[]
>(providers, {
populate: true,
})
return Array.isArray(data) ? serializedProviders : serializedProviders[0]
}
updateAuthProvider(
data: AuthTypes.UpdateAuthProviderDTO[],
sharedContext?: Context
): Promise<AuthProviderDTO[]>
updateAuthProvider(
data: AuthTypes.UpdateAuthProviderDTO,
sharedContext?: Context
): Promise<AuthProviderDTO>
@InjectManager("baseRepository_")
async updateAuthProvider(
data: AuthTypes.UpdateAuthProviderDTO[] | AuthTypes.UpdateAuthProviderDTO,
@MedusaContext() sharedContext: Context = {}
): Promise<AuthTypes.AuthProviderDTO | AuthTypes.AuthProviderDTO[]> {
const input = Array.isArray(data) ? data : [data]
const providers = await this.updateAuthProvider_(input, sharedContext)
const serializedProviders = await this.baseRepository_.serialize<
AuthTypes.AuthProviderDTO[]
>(providers, {
populate: true,
})
return Array.isArray(data) ? serializedProviders : serializedProviders[0]
}
async updateAuthProvider_(
data: AuthTypes.UpdateAuthProviderDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TAuthProvider[]> {
return await this.authProviderService_.update(data, sharedContext)
}
createAuthUser(
create(
data: CreateAuthUserDTO[],
sharedContext?: Context
): Promise<AuthUserDTO[]>
createAuthUser(
data: CreateAuthUserDTO,
sharedContext?: Context
): Promise<AuthUserDTO>
create(data: CreateAuthUserDTO, sharedContext?: Context): Promise<AuthUserDTO>
@InjectManager("baseRepository_")
async createAuthUser(
async create(
data: CreateAuthUserDTO[] | CreateAuthUserDTO,
@MedusaContext() sharedContext: Context = {}
): Promise<AuthTypes.AuthUserDTO | AuthTypes.AuthUserDTO[]> {
const input = Array.isArray(data) ? data : [data]
const authUsers = await this.createAuthUsers_(input, sharedContext)
const authUsers = await this.authUserService_.create(data, sharedContext)
const serializedUsers = await this.baseRepository_.serialize<
AuthTypes.AuthUserDTO[]
@@ -165,28 +80,23 @@ export default class AuthModuleService<
populate: true,
})
return Array.isArray(data) ? serializedUsers : serializedUsers[0]
return serializedUsers
}
updateAuthUser(
update(
data: UpdateAuthUserDTO[],
sharedContext?: Context
): Promise<AuthUserDTO[]>
updateAuthUser(
data: UpdateAuthUserDTO,
sharedContext?: Context
): Promise<AuthUserDTO>
update(data: UpdateAuthUserDTO, sharedContext?: Context): Promise<AuthUserDTO>
// TODO: should be pluralized, see convention about the methods naming or the abstract module service interface definition @engineering
@InjectManager("baseRepository_")
async updateAuthUser(
async update(
data: UpdateAuthUserDTO | UpdateAuthUserDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<AuthTypes.AuthUserDTO | AuthTypes.AuthUserDTO[]> {
const input = Array.isArray(data) ? data : [data]
const updatedUsers = await this.updateAuthUsers_(input, sharedContext)
const updatedUsers = await this.authUserService_.update(data, sharedContext)
const serializedUsers = await this.baseRepository_.serialize<
AuthTypes.AuthUserDTO[]
@@ -197,14 +107,6 @@ export default class AuthModuleService<
return Array.isArray(data) ? serializedUsers : serializedUsers[0]
}
@InjectTransactionManager("baseRepository_")
protected async updateAuthUsers_(
data: UpdateAuthUserDTO[],
@MedusaContext() sharedContext: Context
): Promise<TAuthUser[]> {
return await this.authUserService_.update(data, sharedContext)
}
protected getRegisteredAuthenticationProvider(
provider: string,
{ authScope }: AuthenticationInput
@@ -215,13 +117,11 @@ export default class AuthModuleService<
} catch (error) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`AuthenticationProvider with for provider: ${provider} wasn't registered in the module. Have you configured your options correctly?`
`AuthenticationProvider: ${provider} wasn't registered in the module. Have you configured your options correctly?`
)
}
containerProvider.validateScope(authScope)
return containerProvider
return containerProvider.withScope(authScope)
}
async authenticate(
@@ -229,8 +129,6 @@ export default class AuthModuleService<
authenticationData: AuthenticationInput
): Promise<AuthenticationResponse> {
try {
await this.retrieveAuthProvider(provider, {})
const registeredProvider = this.getRegisteredAuthenticationProvider(
provider,
authenticationData
@@ -247,8 +145,6 @@ export default class AuthModuleService<
authenticationData: AuthenticationInput
): Promise<AuthenticationResponse> {
try {
await this.retrieveAuthProvider(provider, {})
const registeredProvider = this.getRegisteredAuthenticationProvider(
provider,
authenticationData
@@ -259,45 +155,4 @@ export default class AuthModuleService<
return { success: false, error: error.message }
}
}
@InjectTransactionManager("baseRepository_")
protected async createAuthProviders_(
data: any[],
@MedusaContext() sharedContext: Context
): Promise<TAuthProvider[]> {
return await this.authProviderService_.create(data, sharedContext)
}
@InjectTransactionManager("baseRepository_")
protected async createAuthUsers_(
data: CreateAuthUserDTO[],
@MedusaContext() sharedContext: Context
): Promise<TAuthUser[]> {
return await this.authUserService_.create(data, sharedContext)
}
private async createProvidersOnLoad() {
const providersToLoad = this.__container__["auth_providers"]
const providers = await this.authProviderService_.list({
provider: providersToLoad.map((p) => p.provider),
})
const loadedProvidersMap = new Map(providers.map((p) => [p.provider, p]))
const providersToCreate: ServiceTypes.CreateAuthProviderDTO[] = []
for (const provider of providersToLoad) {
if (loadedProvidersMap.has(provider.provider)) {
continue
}
providersToCreate.push({
provider: provider.provider,
name: provider.displayName,
})
}
await this.authProviderService_.create(providersToCreate)
}
}

View File

@@ -1,26 +0,0 @@
import { AuthProvider } from "@models"
export type CreateAuthProviderDTO = {
provider: string
name: string
domain?: ProviderDomain
is_active?: boolean
config?: Record<string, unknown>
}
export type UpdateAuthProviderDTO = {
update: {
provider: string
name?: string
domain?: ProviderDomain
is_active?: boolean
config?: Record<string, unknown>
}
provider: AuthProvider
}
export enum ProviderDomain {
ALL = "all",
STORE = "store",
ADMIN = "admin",
}

View File

@@ -1,2 +1 @@
export * from "./auth-user"
export * from "./auth-provider"

View File

@@ -1,24 +0,0 @@
export type AuthProviderDTO = {
provider: string
name: string
scope: string
is_active: boolean
config: Record<string, unknown>
}
export type CreateAuthProviderDTO = {
provider: string
name: string
scope?: string
is_active?: boolean
config?: Record<string, unknown>
}
export type UpdateAuthProviderDTO = {
provider: string
name?: string
is_active?: boolean
config?: Record<string, unknown>
}
export type FilterableAuthProviderProps = {}

View File

@@ -1,11 +1,9 @@
import { AuthProviderDTO } from "./auth-provider"
export type AuthUserDTO = {
id: string
provider_id: string
entity_id: string
scope: string
provider: AuthProviderDTO
provider: string
provider_metadata?: Record<string, unknown>
user_metadata: Record<string, unknown>
app_metadata: Record<string, unknown>

View File

@@ -1,2 +1 @@
export * from "./auth-user"
export * from "./auth-provider"

View File

@@ -1,4 +1,5 @@
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
import { IAuthModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { isDefined } from "@medusajs/utils"
@@ -17,7 +18,7 @@ export const setAuthAppMetadataStep = createStep(
ModuleRegistrationName.AUTH
)
const authUser = await service.retrieveAuthUser(data.authUserId)
const authUser = await service.retrieve(data.authUserId)
const appMetadata = authUser.app_metadata || {}
if (isDefined(appMetadata[data.key])) {
@@ -26,7 +27,7 @@ export const setAuthAppMetadataStep = createStep(
appMetadata[data.key] = data.value
await service.updateAuthUser({
await service.update({
id: authUser.id,
app_metadata: appMetadata,
})
@@ -44,14 +45,14 @@ export const setAuthAppMetadataStep = createStep(
ModuleRegistrationName.AUTH
)
const authUser = await service.retrieveAuthUser(id)
const authUser = await service.retrieve(id)
const appMetadata = authUser.app_metadata || {}
if (isDefined(appMetadata[key])) {
delete appMetadata[key]
}
await service.updateAuthUser({
await service.update({
id: authUser.id,
app_metadata: appMetadata,
})

View File

@@ -1,8 +1,8 @@
import { ICustomerModuleService } from "@medusajs/types"
import { MikroOrmWrapper } from "../../../utils"
import { Modules } from "@medusajs/modules-sdk"
import { initModules } from "medusa-test-utils"
import { getInitModuleConfig } from "../../../utils/get-init-module-config"
import { initModules } from "medusa-test-utils"
jest.setTimeout(30000)

View File

@@ -1,33 +0,0 @@
import { BaseFilterable } from "../../dal"
export type AuthProviderDTO = {
provider: string
name: string
scope?: string
is_active: boolean
config: Record<string, unknown> | null
}
export type CreateAuthProviderDTO = {
provider: string
name: string
scope?: string
is_active?: boolean
config?: Record<string, unknown>
}
export type UpdateAuthProviderDTO = {
provider: string
name?: string
is_active?: boolean
config?: Record<string, unknown>
}
export interface FilterableAuthProviderProps
extends BaseFilterable<FilterableAuthProviderProps> {
id?: string | string[]
provider?: string[]
is_active?: boolean
scope?: string[]
name?: string[]
}

View File

@@ -1,18 +1,17 @@
import { AuthProviderDTO } from "./auth-provider"
import { BaseFilterable } from "../../dal"
export type AuthUserDTO = {
id: string
provider_id: string
provider: string
entity_id: string
scope: string
provider: AuthProviderDTO
provider_metadata?: Record<string, unknown>
user_metadata: Record<string, unknown>
app_metadata: Record<string, unknown>
}
export type CreateAuthUserDTO = {
id?: string
provider: string
entity_id: string
scope: string

View File

@@ -1,3 +1,2 @@
export * from "./auth-user"
export * from "./auth-provider"
export * from "./provider"

View File

@@ -1,13 +1,9 @@
import {
AuthUserDTO,
AuthenticationInput,
AuthenticationResponse,
AuthProviderDTO,
AuthUserDTO,
CreateAuthProviderDTO,
CreateAuthUserDTO,
FilterableAuthProviderProps,
FilterableAuthUserProps,
UpdateAuthProviderDTO,
UpdateAuthUserDTO,
} from "./common"
@@ -30,83 +26,37 @@ export interface IAuthModuleService extends IModuleService {
providerData: AuthenticationInput
): Promise<AuthenticationResponse>
retrieveAuthProvider(
provider: string,
config?: FindConfig<AuthProviderDTO>,
sharedContext?: Context
): Promise<AuthProviderDTO>
listAuthProviders(
filters?: FilterableAuthProviderProps,
config?: FindConfig<AuthProviderDTO>,
sharedContext?: Context
): Promise<AuthProviderDTO[]>
listAndCountAuthProviders(
filters?: FilterableAuthProviderProps,
config?: FindConfig<AuthProviderDTO>,
sharedContext?: Context
): Promise<[AuthProviderDTO[], number]>
createAuthProvider(
data: CreateAuthProviderDTO[],
sharedContext?: Context
): Promise<AuthProviderDTO[]>
createAuthProvider(
data: CreateAuthProviderDTO,
sharedContext?: Context
): Promise<AuthProviderDTO>
updateAuthProvider(
data: UpdateAuthProviderDTO[],
sharedContext?: Context
): Promise<AuthProviderDTO[]>
updateAuthProvider(
data: UpdateAuthProviderDTO,
sharedContext?: Context
): Promise<AuthProviderDTO>
deleteAuthProviders(ids: string[], sharedContext?: Context): Promise<void>
retrieveAuthUser(
retrieve(
id: string,
config?: FindConfig<AuthUserDTO>,
sharedContext?: Context
): Promise<AuthUserDTO>
listAuthUsers(
filters?: FilterableAuthProviderProps,
list(
filters?: FilterableAuthUserProps,
config?: FindConfig<AuthUserDTO>,
sharedContext?: Context
): Promise<AuthUserDTO[]>
listAndCountAuthUsers(
listAndCount(
filters?: FilterableAuthUserProps,
config?: FindConfig<AuthUserDTO>,
sharedContext?: Context
): Promise<[AuthUserDTO[], number]>
createAuthUser(
create(
data: CreateAuthUserDTO[],
sharedContext?: Context
): Promise<AuthUserDTO[]>
createAuthUser(
data: CreateAuthUserDTO,
sharedContext?: Context
): Promise<AuthUserDTO>
create(data: CreateAuthUserDTO, sharedContext?: Context): Promise<AuthUserDTO>
updateAuthUser(
update(
data: UpdateAuthUserDTO[],
sharedContext?: Context
): Promise<AuthUserDTO[]>
updateAuthUser(
data: UpdateAuthUserDTO,
sharedContext?: Context
): Promise<AuthUserDTO>
update(data: UpdateAuthUserDTO, sharedContext?: Context): Promise<AuthUserDTO>
deleteAuthUsers(ids: string[], sharedContext?: Context): Promise<void>
delete(ids: string[], sharedContext?: Context): Promise<void>
}

View File

@@ -5,22 +5,34 @@ import { MedusaError } from "../common"
export abstract class AbstractAuthModuleProvider {
public static PROVIDER: string
public static DISPLAY_NAME: string
protected readonly scopes_: Record<string, AuthProviderScope>
protected readonly container_: any
protected scopeConfig_: AuthProviderScope
protected scope_: string
private readonly scopes_: Record<string, AuthProviderScope>
public get provider() {
return (this.constructor as Function & { PROVIDER: string }).PROVIDER
return (this.constructor as typeof AbstractAuthModuleProvider).PROVIDER
}
public get displayName() {
return (this.constructor as Function & { DISPLAY_NAME: string })
.DISPLAY_NAME
return (this.constructor as typeof AbstractAuthModuleProvider).DISPLAY_NAME
}
protected constructor({ scopes }) {
protected constructor(
{ scopes },
config: { provider: string; displayName: string }
) {
this.container_ = arguments[0]
this.scopes_ = scopes
;(this.constructor as typeof AbstractAuthModuleProvider).PROVIDER ??=
config.provider
;(this.constructor as typeof AbstractAuthModuleProvider).DISPLAY_NAME ??=
config.displayName
}
public validateScope(scope) {
private validateScope(scope) {
if (!this.scopes_[scope]) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
@@ -29,6 +41,16 @@ export abstract class AbstractAuthModuleProvider {
}
}
public withScope(scope: string) {
this.validateScope(scope)
const cloned = new (this.constructor as any)(this.container_)
cloned.scope_ = scope
cloned.scopeConfg_ = this.scopes_[scope]
return cloned
}
abstract authenticate(
data: Record<string, unknown>
): Promise<AuthenticationResponse>

View File

@@ -1,6 +1,6 @@
import { DAL, FindConfig } from "@medusajs/types"
import { deduplicate, isDefined, isObject } from "../common"
import { SoftDeletableFilterKey } from "../dal"
export function buildQuery<T = any, TDto = any>(