From 882aa549bdcc6f378934eab2a7c485df354f46aa Mon Sep 17 00:00:00 2001 From: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:54:34 +0800 Subject: [PATCH] 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> --- .changeset/smooth-penguins-vanish.md | 5 + .../store/create-customer-addresses.ts | 7 +- .../customer/store/create-customer.spec.ts | 2 +- .../store/delete-customer-address.spec.ts | 24 +- .../__tests__/customer/store/get-me.spec.ts | 8 +- .../customer/store/list-customer-addresses.ts | 7 +- .../store/update-customer-address.spec.ts | 24 +- .../helpers/create-authenticated-customer.ts | 19 +- .../__fixtures__/auth-provider/index.ts | 41 --- .../services/auth-provider/index.spec.ts | 271 ----------------- .../services/auth-user/index.spec.ts | 8 +- .../services/module/auth-provider.spec.ts | 274 ------------------ .../services/module/auth-user.spec.ts | 62 ++-- .../services/module/providers.spec.ts | 34 +-- .../providers/username-password.spec.ts | 4 - .../src/migrations/.snapshot-medusa-auth.json | 88 +----- .../src/migrations/Migration20240201100135.ts | 22 -- .../src/migrations/Migration20240205025924.ts | 16 + packages/auth/src/models/auth-provider.ts | 31 -- packages/auth/src/models/auth-user.ts | 9 +- packages/auth/src/models/index.ts | 1 - packages/auth/src/providers/email-password.ts | 16 +- packages/auth/src/providers/google.ts | 36 ++- packages/auth/src/services/auth-module.ts | 179 ++---------- .../src/types/repositories/auth-provider.ts | 26 -- packages/auth/src/types/repositories/index.ts | 1 - .../auth/src/types/services/auth-provider.ts | 24 -- packages/auth/src/types/services/auth-user.ts | 4 +- packages/auth/src/types/services/index.ts | 1 - .../src/auth/steps/set-auth-app-metadata.ts | 9 +- .../services/customer-module/index.spec.ts | 2 +- .../types/src/auth/common/auth-provider.ts | 33 --- packages/types/src/auth/common/auth-user.ts | 5 +- packages/types/src/auth/common/index.ts | 1 - packages/types/src/auth/service.ts | 70 +---- .../utils/src/auth/abstract-auth-provider.ts | 34 ++- packages/utils/src/modules-sdk/build-query.ts | 2 +- 37 files changed, 178 insertions(+), 1222 deletions(-) create mode 100644 .changeset/smooth-penguins-vanish.md delete mode 100644 packages/auth/integration-tests/__fixtures__/auth-provider/index.ts delete mode 100644 packages/auth/integration-tests/__tests__/services/auth-provider/index.spec.ts delete mode 100644 packages/auth/integration-tests/__tests__/services/module/auth-provider.spec.ts delete mode 100644 packages/auth/src/migrations/Migration20240201100135.ts create mode 100644 packages/auth/src/migrations/Migration20240205025924.ts delete mode 100644 packages/auth/src/models/auth-provider.ts delete mode 100644 packages/auth/src/types/repositories/auth-provider.ts delete mode 100644 packages/auth/src/types/services/auth-provider.ts delete mode 100644 packages/types/src/auth/common/auth-provider.ts diff --git a/.changeset/smooth-penguins-vanish.md b/.changeset/smooth-penguins-vanish.md new file mode 100644 index 0000000000000..0ab9af34605e4 --- /dev/null +++ b/.changeset/smooth-penguins-vanish.md @@ -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 diff --git a/integration-tests/plugins/__tests__/customer/store/create-customer-addresses.ts b/integration-tests/plugins/__tests__/customer/store/create-customer-addresses.ts index cd93c6d9fa41a..ae7d13a12841a 100644 --- a/integration-tests/plugins/__tests__/customer/store/create-customer-addresses.ts +++ b/integration-tests/plugins/__tests__/customer/store/create-customer-addresses.ts @@ -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( diff --git a/integration-tests/plugins/__tests__/customer/store/create-customer.spec.ts b/integration-tests/plugins/__tests__/customer/store/create-customer.spec.ts index 7048092f9e46f..b196c6cd9d31d 100644 --- a/integration-tests/plugins/__tests__/customer/store/create-customer.spec.ts +++ b/integration-tests/plugins/__tests__/customer/store/create-customer.spec.ts @@ -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", diff --git a/integration-tests/plugins/__tests__/customer/store/delete-customer-address.spec.ts b/integration-tests/plugins/__tests__/customer/store/delete-customer-address.spec.ts index c5af2699b535c..723163e74da69 100644 --- a/integration-tests/plugins/__tests__/customer/store/delete-customer-address.spec.ts +++ b/integration-tests/plugins/__tests__/customer/store/delete-customer-address.spec.ts @@ -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", diff --git a/integration-tests/plugins/__tests__/customer/store/get-me.spec.ts b/integration-tests/plugins/__tests__/customer/store/get-me.spec.ts index 4600a0b2a9e51..d30fca0bc8f8a 100644 --- a/integration-tests/plugins/__tests__/customer/store/get-me.spec.ts +++ b/integration-tests/plugins/__tests__/customer/store/get-me.spec.ts @@ -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`, { diff --git a/integration-tests/plugins/__tests__/customer/store/list-customer-addresses.ts b/integration-tests/plugins/__tests__/customer/store/list-customer-addresses.ts index 9881982fce74f..4e7cf975828ff 100644 --- a/integration-tests/plugins/__tests__/customer/store/list-customer-addresses.ts +++ b/integration-tests/plugins/__tests__/customer/store/list-customer-addresses.ts @@ -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([ { diff --git a/integration-tests/plugins/__tests__/customer/store/update-customer-address.spec.ts b/integration-tests/plugins/__tests__/customer/store/update-customer-address.spec.ts index 22850130ff6ed..3401650f2069d 100644 --- a/integration-tests/plugins/__tests__/customer/store/update-customer-address.spec.ts +++ b/integration-tests/plugins/__tests__/customer/store/update-customer-address.spec.ts @@ -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", diff --git a/integration-tests/plugins/helpers/create-authenticated-customer.ts b/integration-tests/plugins/helpers/create-authenticated-customer.ts index 903dd172aa215..3c355bf8e601a 100644 --- a/integration-tests/plugins/helpers/create-authenticated-customer.ts +++ b/integration-tests/plugins/helpers/create-authenticated-customer.ts @@ -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 = {} ) => { + 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 } } diff --git a/packages/auth/integration-tests/__fixtures__/auth-provider/index.ts b/packages/auth/integration-tests/__fixtures__/auth-provider/index.ts deleted file mode 100644 index c21f9be7b10cc..0000000000000 --- a/packages/auth/integration-tests/__fixtures__/auth-provider/index.ts +++ /dev/null @@ -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 { - const authProviders: AuthProvider[] = [] - - for (const provider of providerData) { - const authProvider = manager.create(AuthProvider, provider) - - authProviders.push(authProvider) - } - - await manager.persistAndFlush(authProviders) - - return authProviders -} diff --git a/packages/auth/integration-tests/__tests__/services/auth-provider/index.spec.ts b/packages/auth/integration-tests/__tests__/services/auth-provider/index.spec.ts deleted file mode 100644 index 3ce97ecd458e4..0000000000000 --- a/packages/auth/integration-tests/__tests__/services/auth-provider/index.spec.ts +++ /dev/null @@ -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 - 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", - }) - ) - }) - }) -}) diff --git a/packages/auth/integration-tests/__tests__/services/auth-user/index.spec.ts b/packages/auth/integration-tests/__tests__/services/auth-user/index.spec.ts index 7dd4afe52e3b0..32dd1aa819f8f 100644 --- a/packages/auth/integration-tests/__tests__/services/auth-user/index.spec.ts +++ b/packages/auth/integration-tests/__tests__/services/auth-user/index.spec.ts @@ -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", }, diff --git a/packages/auth/integration-tests/__tests__/services/module/auth-provider.spec.ts b/packages/auth/integration-tests/__tests__/services/module/auth-provider.spec.ts deleted file mode 100644 index 96034b5518aab..0000000000000 --- a/packages/auth/integration-tests/__tests__/services/module/auth-provider.spec.ts +++ /dev/null @@ -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 - - 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", - }) - ) - }) - }) -}) diff --git a/packages/auth/integration-tests/__tests__/services/module/auth-user.spec.ts b/packages/auth/integration-tests/__tests__/services/module/auth-user.spec.ts index cd812040da700..2a45edeeb6e30 100644 --- a/packages/auth/integration-tests/__tests__/services/module/auth-user.spec.ts +++ b/packages/auth/integration-tests/__tests__/services/module/auth-user.spec.ts @@ -1,11 +1,10 @@ -import { Modules } from "@medusajs/modules-sdk" import { IAuthModuleService } from "@medusajs/types" +import { MikroOrmWrapper } from "../../../utils" +import { Modules } from "@medusajs/modules-sdk" 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" +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"], }) diff --git a/packages/auth/integration-tests/__tests__/services/module/providers.spec.ts b/packages/auth/integration-tests/__tests__/services/module/providers.spec.ts index a92aa56cde109..2be6a351f2b8f 100644 --- a/packages/auth/integration-tests/__tests__/services/module/providers.spec.ts +++ b/packages/auth/integration-tests/__tests__/services/module/providers.spec.ts @@ -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?" ) }) diff --git a/packages/auth/integration-tests/__tests__/services/providers/username-password.spec.ts b/packages/auth/integration-tests/__tests__/services/providers/username-password.spec.ts index 7e3955d71b9b5..ee24625214ddc 100644 --- a/packages/auth/integration-tests/__tests__/services/providers/username-password.spec.ts +++ b/packages/auth/integration-tests/__tests__/services/providers/username-password.spec.ts @@ -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", { diff --git a/packages/auth/src/migrations/.snapshot-medusa-auth.json b/packages/auth/src/migrations/.snapshot-medusa-auth.json index 294b0a9ba5d4b..2e72233a4573b 100644 --- a/packages/auth/src/migrations/.snapshot-medusa-auth.json +++ b/packages/auth/src/migrations/.snapshot-medusa-auth.json @@ -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": {} } ] } diff --git a/packages/auth/src/migrations/Migration20240201100135.ts b/packages/auth/src/migrations/Migration20240201100135.ts deleted file mode 100644 index de100203d9a04..0000000000000 --- a/packages/auth/src/migrations/Migration20240201100135.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Migration } from '@mikro-orm/migrations'; - -export class Migration20240201100135 extends Migration { - - async up(): Promise { - 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 { - 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;'); - } - -} diff --git a/packages/auth/src/migrations/Migration20240205025924.ts b/packages/auth/src/migrations/Migration20240205025924.ts new file mode 100644 index 0000000000000..75bd184b2125b --- /dev/null +++ b/packages/auth/src/migrations/Migration20240205025924.ts @@ -0,0 +1,16 @@ +import { Migration } from "@mikro-orm/migrations" + +export class Migration20240205025924 extends Migration { + async up(): Promise { + 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 { + this.addSql('drop table if exists "auth_user" cascade;') + } +} diff --git a/packages/auth/src/models/auth-provider.ts b/packages/auth/src/models/auth-provider.ts deleted file mode 100644 index 39ba51823585d..0000000000000 --- a/packages/auth/src/models/auth-provider.ts +++ /dev/null @@ -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 | null = null - - @Property({ columnType: "boolean", default: false }) - is_active = false -} diff --git a/packages/auth/src/models/auth-user.ts b/packages/auth/src/models/auth-user.ts index 122462c26cdf1..10e4e3b9ff723 100644 --- a/packages/auth/src/models/auth-user.ts +++ b/packages/auth/src/models/auth-user.ts @@ -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 diff --git a/packages/auth/src/models/index.ts b/packages/auth/src/models/index.ts index 56d27c3d137dc..e5b8ee0f1c6cf 100644 --- a/packages/auth/src/models/index.ts +++ b/packages/auth/src/models/index.ts @@ -1,2 +1 @@ export { default as AuthUser } from "./auth-user" -export { default as AuthProvider } from "./auth-provider" diff --git a/packages/auth/src/providers/email-password.ts b/packages/auth/src/providers/email-password.ts index da2617ef2a81f..fc239438a79fc 100644 --- a/packages/auth/src/providers/email-password.ts +++ b/packages/auth/src/providers/email-password.ts @@ -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"), }, diff --git a/packages/auth/src/providers/google.ts b/packages/auth/src/providers/google.ts index 7cc0404a5f25e..a6b2ffff1a1b1 100644 --- a/packages/auth/src/providers/google.ts +++ b/packages/auth/src/providers/google.ts @@ -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 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 { - const providerConfig: Partial = { ...config } + private getConfigFromScope(): ProviderConfig { + const config: Partial = { ...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 { await this.authProviderService_.retrieve(GoogleProvider.PROVIDER) - const scopeConfig = this.scopes_[req.authScope] - - const config = this.getConfigFromScope(scopeConfig) + const config = this.getConfigFromScope() - const { callbackURL } = config + const callbackURL = config.callbackURL const parsedCallbackUrl = !url.parse(callbackURL).protocol ? url.resolve(this.originalURL(req), callbackURL) diff --git a/packages/auth/src/services/auth-module.ts b/packages/auth/src/services/auth-module.ts index 6ac7dd2dc6266..83940d1e255d1 100644 --- a/packages/auth/src/services/auth-module.ts +++ b/packages/auth/src/services/auth-module.ts @@ -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 - authProviderService: ModulesSdkTypes.InternalModuleService } -const generateMethodForModels = [AuthProvider, AuthUser] +const generateMethodForModels = [AuthUser] -export default class AuthModuleService< - TAuthUser extends AuthUser = AuthUser, - TAuthProvider extends AuthProvider = AuthProvider - > +export default class AuthModuleService 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 - protected authProviderService_: ModulesSdkTypes.InternalModuleService 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 - - async createAuthProvider( - data: CreateAuthProviderDTO, - sharedContext?: Context - ): Promise - - @InjectManager("baseRepository_") - async createAuthProvider( - data: CreateAuthProviderDTO | CreateAuthProviderDTO[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - 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 - - updateAuthProvider( - data: AuthTypes.UpdateAuthProviderDTO, - sharedContext?: Context - ): Promise - - @InjectManager("baseRepository_") - async updateAuthProvider( - data: AuthTypes.UpdateAuthProviderDTO[] | AuthTypes.UpdateAuthProviderDTO, - @MedusaContext() sharedContext: Context = {} - ): Promise { - 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 { - return await this.authProviderService_.update(data, sharedContext) - } - - createAuthUser( + create( data: CreateAuthUserDTO[], sharedContext?: Context ): Promise - createAuthUser( - data: CreateAuthUserDTO, - sharedContext?: Context - ): Promise + create(data: CreateAuthUserDTO, sharedContext?: Context): Promise @InjectManager("baseRepository_") - async createAuthUser( + async create( data: CreateAuthUserDTO[] | CreateAuthUserDTO, @MedusaContext() sharedContext: Context = {} ): Promise { - 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 - updateAuthUser( - data: UpdateAuthUserDTO, - sharedContext?: Context - ): Promise + update(data: UpdateAuthUserDTO, sharedContext?: Context): Promise // 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 { - 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 { - 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 { try { - await this.retrieveAuthProvider(provider, {}) - const registeredProvider = this.getRegisteredAuthenticationProvider( provider, authenticationData @@ -247,8 +145,6 @@ export default class AuthModuleService< authenticationData: AuthenticationInput ): Promise { 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 { - return await this.authProviderService_.create(data, sharedContext) - } - - @InjectTransactionManager("baseRepository_") - protected async createAuthUsers_( - data: CreateAuthUserDTO[], - @MedusaContext() sharedContext: Context - ): Promise { - 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) - } } diff --git a/packages/auth/src/types/repositories/auth-provider.ts b/packages/auth/src/types/repositories/auth-provider.ts deleted file mode 100644 index 6f1ea0dc88e0f..0000000000000 --- a/packages/auth/src/types/repositories/auth-provider.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { AuthProvider } from "@models" - -export type CreateAuthProviderDTO = { - provider: string - name: string - domain?: ProviderDomain - is_active?: boolean - config?: Record -} - -export type UpdateAuthProviderDTO = { - update: { - provider: string - name?: string - domain?: ProviderDomain - is_active?: boolean - config?: Record - } - provider: AuthProvider -} - -export enum ProviderDomain { - ALL = "all", - STORE = "store", - ADMIN = "admin", -} diff --git a/packages/auth/src/types/repositories/index.ts b/packages/auth/src/types/repositories/index.ts index b4282c985c6a3..0a25390ceac82 100644 --- a/packages/auth/src/types/repositories/index.ts +++ b/packages/auth/src/types/repositories/index.ts @@ -1,2 +1 @@ export * from "./auth-user" -export * from "./auth-provider" diff --git a/packages/auth/src/types/services/auth-provider.ts b/packages/auth/src/types/services/auth-provider.ts deleted file mode 100644 index dc400222e43a1..0000000000000 --- a/packages/auth/src/types/services/auth-provider.ts +++ /dev/null @@ -1,24 +0,0 @@ -export type AuthProviderDTO = { - provider: string - name: string - scope: string - is_active: boolean - config: Record -} - -export type CreateAuthProviderDTO = { - provider: string - name: string - scope?: string - is_active?: boolean - config?: Record -} - -export type UpdateAuthProviderDTO = { - provider: string - name?: string - is_active?: boolean - config?: Record -} - -export type FilterableAuthProviderProps = {} diff --git a/packages/auth/src/types/services/auth-user.ts b/packages/auth/src/types/services/auth-user.ts index bab3e0c2e4f9d..4e0deaabc19bf 100644 --- a/packages/auth/src/types/services/auth-user.ts +++ b/packages/auth/src/types/services/auth-user.ts @@ -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 user_metadata: Record app_metadata: Record diff --git a/packages/auth/src/types/services/index.ts b/packages/auth/src/types/services/index.ts index b4282c985c6a3..0a25390ceac82 100644 --- a/packages/auth/src/types/services/index.ts +++ b/packages/auth/src/types/services/index.ts @@ -1,2 +1 @@ export * from "./auth-user" -export * from "./auth-provider" diff --git a/packages/core-flows/src/auth/steps/set-auth-app-metadata.ts b/packages/core-flows/src/auth/steps/set-auth-app-metadata.ts index 7b5d9809d463f..406b078a17aed 100644 --- a/packages/core-flows/src/auth/steps/set-auth-app-metadata.ts +++ b/packages/core-flows/src/auth/steps/set-auth-app-metadata.ts @@ -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, }) diff --git a/packages/customer/integration-tests/__tests__/services/customer-module/index.spec.ts b/packages/customer/integration-tests/__tests__/services/customer-module/index.spec.ts index ae5236c734d76..49f676475b24d 100644 --- a/packages/customer/integration-tests/__tests__/services/customer-module/index.spec.ts +++ b/packages/customer/integration-tests/__tests__/services/customer-module/index.spec.ts @@ -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) diff --git a/packages/types/src/auth/common/auth-provider.ts b/packages/types/src/auth/common/auth-provider.ts deleted file mode 100644 index ddf833879748f..0000000000000 --- a/packages/types/src/auth/common/auth-provider.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { BaseFilterable } from "../../dal" - -export type AuthProviderDTO = { - provider: string - name: string - scope?: string - is_active: boolean - config: Record | null -} - -export type CreateAuthProviderDTO = { - provider: string - name: string - scope?: string - is_active?: boolean - config?: Record -} - -export type UpdateAuthProviderDTO = { - provider: string - name?: string - is_active?: boolean - config?: Record -} - -export interface FilterableAuthProviderProps - extends BaseFilterable { - id?: string | string[] - provider?: string[] - is_active?: boolean - scope?: string[] - name?: string[] -} diff --git a/packages/types/src/auth/common/auth-user.ts b/packages/types/src/auth/common/auth-user.ts index 1946e360830a2..884ac90d276e7 100644 --- a/packages/types/src/auth/common/auth-user.ts +++ b/packages/types/src/auth/common/auth-user.ts @@ -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 user_metadata: Record app_metadata: Record } export type CreateAuthUserDTO = { + id?: string provider: string entity_id: string scope: string diff --git a/packages/types/src/auth/common/index.ts b/packages/types/src/auth/common/index.ts index 332e78fe42975..0b9e82d47e937 100644 --- a/packages/types/src/auth/common/index.ts +++ b/packages/types/src/auth/common/index.ts @@ -1,3 +1,2 @@ export * from "./auth-user" -export * from "./auth-provider" export * from "./provider" diff --git a/packages/types/src/auth/service.ts b/packages/types/src/auth/service.ts index 06890dc151333..a2eb84ba5b539 100644 --- a/packages/types/src/auth/service.ts +++ b/packages/types/src/auth/service.ts @@ -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 - retrieveAuthProvider( - provider: string, - config?: FindConfig, - sharedContext?: Context - ): Promise - - listAuthProviders( - filters?: FilterableAuthProviderProps, - config?: FindConfig, - sharedContext?: Context - ): Promise - - listAndCountAuthProviders( - filters?: FilterableAuthProviderProps, - config?: FindConfig, - sharedContext?: Context - ): Promise<[AuthProviderDTO[], number]> - - createAuthProvider( - data: CreateAuthProviderDTO[], - sharedContext?: Context - ): Promise - - createAuthProvider( - data: CreateAuthProviderDTO, - sharedContext?: Context - ): Promise - - updateAuthProvider( - data: UpdateAuthProviderDTO[], - sharedContext?: Context - ): Promise - - updateAuthProvider( - data: UpdateAuthProviderDTO, - sharedContext?: Context - ): Promise - - deleteAuthProviders(ids: string[], sharedContext?: Context): Promise - - retrieveAuthUser( + retrieve( id: string, config?: FindConfig, sharedContext?: Context ): Promise - listAuthUsers( - filters?: FilterableAuthProviderProps, + list( + filters?: FilterableAuthUserProps, config?: FindConfig, sharedContext?: Context ): Promise - listAndCountAuthUsers( + listAndCount( filters?: FilterableAuthUserProps, config?: FindConfig, sharedContext?: Context ): Promise<[AuthUserDTO[], number]> - createAuthUser( + create( data: CreateAuthUserDTO[], sharedContext?: Context ): Promise - createAuthUser( - data: CreateAuthUserDTO, - sharedContext?: Context - ): Promise + create(data: CreateAuthUserDTO, sharedContext?: Context): Promise - updateAuthUser( + update( data: UpdateAuthUserDTO[], sharedContext?: Context ): Promise - updateAuthUser( - data: UpdateAuthUserDTO, - sharedContext?: Context - ): Promise + update(data: UpdateAuthUserDTO, sharedContext?: Context): Promise - deleteAuthUsers(ids: string[], sharedContext?: Context): Promise + delete(ids: string[], sharedContext?: Context): Promise } diff --git a/packages/utils/src/auth/abstract-auth-provider.ts b/packages/utils/src/auth/abstract-auth-provider.ts index e502e4b29e6e4..9a1d4682d8fa9 100644 --- a/packages/utils/src/auth/abstract-auth-provider.ts +++ b/packages/utils/src/auth/abstract-auth-provider.ts @@ -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 + + protected readonly container_: any + protected scopeConfig_: AuthProviderScope + protected scope_: string + + private readonly scopes_: Record 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 ): Promise diff --git a/packages/utils/src/modules-sdk/build-query.ts b/packages/utils/src/modules-sdk/build-query.ts index 912725d58999e..99b261279b6a1 100644 --- a/packages/utils/src/modules-sdk/build-query.ts +++ b/packages/utils/src/modules-sdk/build-query.ts @@ -1,6 +1,6 @@ import { DAL, FindConfig } from "@medusajs/types" - import { deduplicate, isDefined, isObject } from "../common" + import { SoftDeletableFilterKey } from "../dal" export function buildQuery(