diff --git a/packages/core/types/src/auth/common/auth-identity.ts b/packages/core/types/src/auth/common/auth-identity.ts index 912577a030..b1308874a1 100644 --- a/packages/core/types/src/auth/common/auth-identity.ts +++ b/packages/core/types/src/auth/common/auth-identity.ts @@ -152,7 +152,7 @@ export type UpdateProviderIdentityDTO = { * The user's identifier. For example, when using the `emailpass` * provider, the `entity_id` would be the user's email. */ - entity_id: string + entity_id?: string /** * Holds custom data related to the provider in key-value pairs. @@ -192,3 +192,31 @@ export interface FilterableAuthIdentityProps app_metadata?: Record } + +export interface FilterableProviderIdentityProps + extends BaseFilterable { + /** + * The IDs to filter the provider identity by. + */ + id?: string[] + + /** + * Filter the provider identities by the ID of the provider identity they are linked to. + */ + entity_id?: string + + /** + * The provider handle to filter the provider identity by. + */ + provider?: string + + /** + * Holds custom data related to the provider in key-value pairs. + */ + provider_metadata?: Record + + /** + * Holds custom data related to the user in key-value pairs. + */ + user_metadata?: Record +} diff --git a/packages/core/types/src/auth/service.ts b/packages/core/types/src/auth/service.ts index 79f2eeb2bc..370d24b06c 100644 --- a/packages/core/types/src/auth/service.ts +++ b/packages/core/types/src/auth/service.ts @@ -8,8 +8,10 @@ import { CreateAuthIdentityDTO, CreateProviderIdentityDTO, FilterableAuthIdentityProps, + FilterableProviderIdentityProps, ProviderIdentityDTO, UpdateAuthIdentityDTO, + UpdateProviderIdentityDTO, } from "./common" /** @@ -277,6 +279,62 @@ export interface IAuthModuleService extends IModuleService { */ deleteAuthIdentities(ids: string[], sharedContext?: Context): Promise + /** + * This method retrieves a provider identity by its ID. + * + * @param {string} id - The ID of the provider identity. + * @param {FindConfig} config - The configurations determining how the provider identity is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a provider identity. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The retrieved provider identity. + * + * @example + * const providerIdentity = await authModuleService.retrieveProviderIdentity("provider_123") + */ + retrieveProviderIdentity( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + + /** + * This method retrieves a paginated list of provider identities based on optional filters and configuration. + * + * @param {FilterableProviderIdentityProps} filters - The filters to apply on the retrieved provider identities. + * @param {FindConfig} config - The configurations determining how the provider identity is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a provider identity. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of provider identities. + * + * @example + * To retrieve a list of provider identities using their IDs: + * + * ```ts + * const providerIdentities = await authModuleService.listProviderIdentities({ + * id: ["provider_123", "provider_234"], + * }) + * ``` + * + * By default, only the first `15` records are retrieved. You can control pagination by specifying the `skip` and `take` properties of the `config` parameter: + * + * ```ts + * const providerIdentities = await authModuleService.listProviderIdentities( + * { + * id: ["provider_123", "provider_234"], + * }, + * { + * take: 20, + * skip: 2, + * } + * ) + * ``` + */ + listProviderIdentities( + filters?: FilterableProviderIdentityProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** * This method creates provider identities. * @@ -321,4 +379,55 @@ export interface IAuthModuleService extends IModuleService { data: CreateProviderIdentityDTO, sharedContext?: Context ): Promise + + /** + * This method updates existing provider identities. + * + * @param {UpdateProviderIdentityDTO[]} data - The attributes to update in the provider identities. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated provider identities. + * + * @example + * const providerIdentities = await authModuleService.updateProviderIdentities([ + * { + * id: "provider_123", + * }, + * ]) + */ + updateProviderIdentites( + data: UpdateProviderIdentityDTO[], + sharedContext?: Context + ): Promise + + /** + * This method updates an existing provider identity. + * + * @param {UpdateProviderIdentityDTO} data - The attributes to update in the provider identity. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated provider identity. + * + * @example + * const providerIdentity = await authModuleService.updateProviderIdentites({ + * id: "provider_123", + * }) + */ + updateProviderIdentites( + data: UpdateProviderIdentityDTO, + sharedContext?: Context + ): Promise + + /** + * This method deletes a provider identity by its ID. + * + * @param {string[]} ids - The IDs of the provider identity. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * await authModuleService.deleteProviderIdentities(["provider_123", "provider_234"]) + */ + deleteProviderIdentities( + ids: string[], + sharedContext?: Context + ): Promise } diff --git a/packages/modules/auth/integration-tests/__fixtures__/auth-identity/index.ts b/packages/modules/auth/integration-tests/__fixtures__/auth-identity/index.ts index ffa4753d8b..20cb4e9f71 100644 --- a/packages/modules/auth/integration-tests/__fixtures__/auth-identity/index.ts +++ b/packages/modules/auth/integration-tests/__fixtures__/auth-identity/index.ts @@ -8,7 +8,7 @@ export async function createAuthIdentities( id: "test-id", provider_identities: [ { - entity_id: "test-id", + entity_id: "provider-test-id", provider: "manual", }, ], @@ -20,7 +20,7 @@ export async function createAuthIdentities( id: "test-id-1", provider_identities: [ { - entity_id: "test-id-1", + entity_id: "provider-test-id-1", provider: "manual", }, ], @@ -28,7 +28,7 @@ export async function createAuthIdentities( { provider_identities: [ { - entity_id: "test-id-2", + entity_id: "provider-test-id-2", provider: "store", }, ], diff --git a/packages/modules/auth/integration-tests/__tests__/auth-module-service/auth-identity.spec.ts b/packages/modules/auth/integration-tests/__tests__/auth-module-service/auth-identity.spec.ts index 01bf778dee..1d40f2db68 100644 --- a/packages/modules/auth/integration-tests/__tests__/auth-module-service/auth-identity.spec.ts +++ b/packages/modules/auth/integration-tests/__tests__/auth-module-service/auth-identity.spec.ts @@ -335,6 +335,73 @@ moduleIntegrationTestRunner({ ]) }) }) + + describe("deleteProviderIdentity", () => { + const entity_id = "provider-test-id" + + it("should delete the providerIdentities given an id successfully", async () => { + let providerIdentities = await service.listProviderIdentities({ + entity_id, + }) + + expect(providerIdentities).toHaveLength(1) + const providerIdentityId = providerIdentities[0].id + + await service.deleteProviderIdentities([providerIdentityId]) + + providerIdentities = await service.listProviderIdentities({ + entity_id, + }) + + expect(providerIdentities).toHaveLength(0) + }) + }) + + describe("updateProviderIdentity", () => { + const entity_id = "provider-test-id" + + it("should throw an error when a id does not exist", async () => { + let error + + try { + await service.updateProviderIdentites([ + { + id: "does-not-exist", + }, + ]) + } catch (e) { + error = e + } + + expect(error.message).toEqual( + 'ProviderIdentity with id "does-not-exist" not found' + ) + }) + + it("should update providerIdentity", async () => { + let [providerIdentity] = await service.listProviderIdentities({ + entity_id, + }) + await service.updateProviderIdentites([ + { + id: providerIdentity.id, + provider_metadata: { email: "test@email.com" }, + }, + ]) + + const providerIdentites = await service.listProviderIdentities({ + id: [providerIdentity.id], + }) + + expect(providerIdentites[0]).toEqual( + expect.objectContaining({ + provider_metadata: expect.objectContaining({ + email: "test@email.com", + }), + }) + ) + }) + }) }) }, }) diff --git a/packages/modules/auth/src/services/auth-module.ts b/packages/modules/auth/src/services/auth-module.ts index ece708d87a..78eb4a39d7 100644 --- a/packages/modules/auth/src/services/auth-module.ts +++ b/packages/modules/auth/src/services/auth-module.ts @@ -149,6 +149,35 @@ export default class AuthModuleService >(providerIdentities) } + updateProviderIdentites( + data: AuthTypes.UpdateProviderIdentityDTO[], + sharedContext?: Context + ): Promise + + updateProviderIdentites( + data: AuthTypes.UpdateProviderIdentityDTO, + sharedContext?: Context + ): Promise + + @InjectManager("baseRepository_") + async updateProviderIdentites( + data: + | AuthTypes.UpdateProviderIdentityDTO + | AuthTypes.UpdateProviderIdentityDTO[], + @MedusaContext() sharedContext: Context = {} + ): Promise { + const updatedProviders = await this.providerIdentityService_.update( + data, + sharedContext + ) + + const serializedProviders = await this.baseRepository_.serialize< + AuthTypes.ProviderIdentityDTO[] + >(updatedProviders) + + return Array.isArray(data) ? serializedProviders : serializedProviders[0] + } + async authenticate( provider: string, authenticationData: AuthenticationInput