import { AuthenticationInput, AuthenticationResponse, AuthIdentityProviderService, AuthTypes, Context, DAL, InternalModuleDeclaration, ModuleJoinerConfig, ModulesSdkTypes, } from "@medusajs/types" import { AuthIdentity } from "@models" import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config" import { InjectManager, MedusaContext, MedusaError, ModulesSdkUtils, } from "@medusajs/utils" import AuthProviderService from "./auth-provider" type InjectedDependencies = { baseRepository: DAL.RepositoryService authIdentityService: ModulesSdkTypes.InternalModuleService authProviderService: AuthProviderService } const generateMethodForModels = [AuthIdentity] export default class AuthModuleService< TAuthIdentity extends AuthIdentity = AuthIdentity > extends ModulesSdkUtils.abstractModuleServiceFactory< InjectedDependencies, AuthTypes.AuthIdentityDTO, { AuthIdentity: { dto: AuthTypes.AuthIdentityDTO } } >(AuthIdentity, generateMethodForModels, entityNameToLinkableKeysMap) implements AuthTypes.IAuthModuleService { protected baseRepository_: DAL.RepositoryService protected authIdentityService_: ModulesSdkTypes.InternalModuleService protected readonly authProviderService_: AuthProviderService constructor( { authIdentityService, authProviderService, baseRepository, }: InjectedDependencies, protected readonly moduleDeclaration: InternalModuleDeclaration ) { // @ts-ignore super(...arguments) this.baseRepository_ = baseRepository this.authIdentityService_ = authIdentityService this.authProviderService_ = authProviderService } __joinerConfig(): ModuleJoinerConfig { return joinerConfig } create( data: AuthTypes.CreateAuthIdentityDTO[], sharedContext?: Context ): Promise create( data: AuthTypes.CreateAuthIdentityDTO, sharedContext?: Context ): Promise @InjectManager("baseRepository_") async create( data: AuthTypes.CreateAuthIdentityDTO[] | AuthTypes.CreateAuthIdentityDTO, @MedusaContext() sharedContext: Context = {} ): Promise { const authIdentities = await this.authIdentityService_.create( data, sharedContext ) return await this.baseRepository_.serialize( authIdentities, { populate: true, } ) } update( data: AuthTypes.UpdateAuthIdentityDTO[], sharedContext?: Context ): Promise update( data: AuthTypes.UpdateAuthIdentityDTO, sharedContext?: Context ): Promise // TODO: should be pluralized, see convention about the methods naming or the abstract module service interface definition @engineering @InjectManager("baseRepository_") async update( data: AuthTypes.UpdateAuthIdentityDTO | AuthTypes.UpdateAuthIdentityDTO[], @MedusaContext() sharedContext: Context = {} ): Promise { const updatedUsers = await this.authIdentityService_.update( data, sharedContext ) const serializedUsers = await this.baseRepository_.serialize< AuthTypes.AuthIdentityDTO[] >(updatedUsers, { populate: true, }) return Array.isArray(data) ? serializedUsers : serializedUsers[0] } async authenticate( provider: string, authenticationData: AuthenticationInput ): Promise { try { return await this.authProviderService_.authenticate( provider, authenticationData, this.getAuthIdentityProviderService() ) } catch (error) { return { success: false, error: error.message } } } async validateCallback( provider: string, authenticationData: AuthenticationInput ): Promise { try { return await this.authProviderService_.validateCallback( provider, authenticationData, this.getAuthIdentityProviderService() ) } catch (error) { return { success: false, error: error.message } } } getAuthIdentityProviderService(): AuthIdentityProviderService { return { retrieve: async ({ entity_id, provider }) => { const authIdentities = await this.authIdentityService_.list({ entity_id, provider, }) if (!authIdentities.length) { throw new MedusaError( MedusaError.Types.NOT_FOUND, `AuthIdentity with entity_id "${entity_id}" not found` ) } if (authIdentities.length > 1) { throw new MedusaError( MedusaError.Types.INVALID_DATA, `Multiple authIdentities found for entity_id "${entity_id}"` ) } return await this.baseRepository_.serialize( authIdentities[0] ) }, create: async (data: AuthTypes.CreateAuthIdentityDTO) => { const createdAuthIdentity = await this.authIdentityService_.create(data) return await this.baseRepository_.serialize( createdAuthIdentity ) }, } } }