diff --git a/.changeset/sixty-boats-flow.md b/.changeset/sixty-boats-flow.md new file mode 100644 index 0000000000..b3a144bb7e --- /dev/null +++ b/.changeset/sixty-boats-flow.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +Convert OauthService to TypeScript diff --git a/packages/medusa/src/services/oauth.js b/packages/medusa/src/services/oauth.js deleted file mode 100644 index e1de71075b..0000000000 --- a/packages/medusa/src/services/oauth.js +++ /dev/null @@ -1,121 +0,0 @@ -import { MedusaError } from "medusa-core-utils" -import { OauthService } from "medusa-interfaces" - -class Oauth extends OauthService { - static Events = { - TOKEN_GENERATED: "oauth.token_generated", - TOKEN_REFRESHED: "oauth.token_refreshed", - } - - constructor(cradle) { - super() - const manager = cradle.manager - - this.manager = manager - this.container_ = cradle - this.oauthRepository_ = cradle.oauthRepository - this.eventBus_ = cradle.eventBusService - } - - retrieveByName(appName) { - const repo = this.manager.getCustomRepository(this.oauthRepository_) - return repo.findOne({ - application_name: appName, - }) - } - - list(selector) { - const repo = this.manager.getCustomRepository(this.oauthRepository_) - return repo.find(selector) - } - - async create(data) { - const repo = this.manager.getCustomRepository(this.oauthRepository_) - - const application = repo.create({ - display_name: data.display_name, - application_name: data.application_name, - install_url: data.install_url, - uninstall_url: data.uninstall_url, - }) - - return repo.save(application) - } - - async update(id, update) { - const repo = this.manager.getCustomRepository(this.oauthRepository_) - const oauth = await repo.findOne({ where: { id } }) - - if ("data" in update) { - oauth.data = update.data - } - - return repo.save(oauth) - } - - async registerOauthApp(appDetails) { - const { application_name } = appDetails - const existing = await this.retrieveByName(application_name) - if (existing) { - return - } - - return this.create(appDetails) - } - - async generateToken(appName, code, state) { - const app = await this.retrieveByName(appName) - const service = this.container_[`${app.application_name}Oauth`] - if (!service) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `An OAuth handler for ${app.display_name} could not be found make sure the plugin is installed` - ) - } - - if (!app.state === state) { - throw new MedusaError( - MedusaError.Types.NOT_ALLOWED, - `${app.display_name} could not match state` - ) - } - - const authData = await service.generateToken(code) - - return this.update(app.id, { - data: authData, - }).then((result) => { - this.eventBus_.emit( - `${Oauth.Events.TOKEN_GENERATED}.${appName}`, - authData - ) - return result - }) - } - - async refreshToken(appName) { - const app = await this.retrieveByName(appName) - const refreshToken = app.data.refresh_token - const service = this.container_[`${app.application_name}Oauth`] - if (!service) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `An OAuth handler for ${app.display_name} could not be found make sure the plugin is installed` - ) - } - - const authData = await service.refreshToken(refreshToken) - - return this.update(app.id, { - data: authData, - }).then((result) => { - this.eventBus_.emit( - `${Oauth.Events.TOKEN_REFRESHED}.${appName}`, - authData - ) - return result - }) - } -} - -export default Oauth diff --git a/packages/medusa/src/services/oauth.ts b/packages/medusa/src/services/oauth.ts new file mode 100644 index 0000000000..8a819c7305 --- /dev/null +++ b/packages/medusa/src/services/oauth.ts @@ -0,0 +1,178 @@ +import { MedusaError } from "medusa-core-utils" +import { EntityManager } from "typeorm" +import { TransactionBaseService } from "../interfaces" +import { Oauth as OAuthModel } from "../models" +import { OauthRepository } from "../repositories/oauth" +import { Selector } from "../types/common" +import { MedusaContainer } from "../types/global" +import { CreateOauthInput, UpdateOauthInput } from "../types/oauth" +import { buildQuery } from "../utils" +import EventBusService from "./event-bus" + +type InjectedDependencies = MedusaContainer & { + manager: EntityManager + eventBusService: EventBusService + oauthRepository: typeof OauthRepository +} + +class Oauth extends TransactionBaseService { + protected manager_: EntityManager + protected transactionManager_: EntityManager | undefined + static Events = { + TOKEN_GENERATED: "oauth.token_generated", + TOKEN_REFRESHED: "oauth.token_refreshed", + } + + protected manager: EntityManager + protected container_: InjectedDependencies + protected oauthRepository_: typeof OauthRepository + protected eventBus_: EventBusService + + constructor(cradle: InjectedDependencies) { + super(cradle) + const manager = cradle.manager + + this.manager = manager + this.container_ = cradle + this.oauthRepository_ = cradle.oauthRepository + this.eventBus_ = cradle.eventBusService + } + + async retrieveByName(appName: string): Promise { + const repo = this.manager.getCustomRepository(this.oauthRepository_) + const oauth = await repo.findOne({ + application_name: appName, + }) + + if (!oauth) { + throw new MedusaError( + MedusaError.Types.NOT_FOUND, + `Oauth application ${appName} not found` + ) + } + + return oauth + } + + async retrieve(oauthId: string): Promise { + const repo = this.manager.getCustomRepository(this.oauthRepository_) + const oauth = await repo.findOne({ + id: oauthId, + }) + + if (!oauth) { + throw new MedusaError( + MedusaError.Types.NOT_FOUND, + `Oauth application with id ${oauthId} not found` + ) + } + + return oauth + } + + async list(selector: Selector): Promise { + const repo = this.manager.getCustomRepository(this.oauthRepository_) + + const query = buildQuery(selector, {}) + + return await repo.find(query) + } + + async create(data: CreateOauthInput): Promise { + return await this.atomicPhase_(async (manager) => { + const repo = manager.getCustomRepository(this.oauthRepository_) + + const application = repo.create({ + display_name: data.display_name, + application_name: data.application_name, + install_url: data.install_url, + uninstall_url: data.uninstall_url, + }) + + return await repo.save(application) + }) + } + + async update(id: string, update: UpdateOauthInput): Promise { + return await this.atomicPhase_(async (manager) => { + const repo = manager.getCustomRepository(this.oauthRepository_) + const oauth = await this.retrieve(id) + + if ("data" in update) { + oauth.data = update.data + } + + return await repo.save(oauth) + }) + } + + async registerOauthApp(appDetails: CreateOauthInput): Promise { + const { application_name } = appDetails + const existing = await this.retrieveByName(application_name) + if (existing) { + return existing + } + + return await this.create(appDetails) + } + + async generateToken( + appName: string, + code: string, + state: string + ): Promise { + const app = await this.retrieveByName(appName) + const service = this.container_[`${app.application_name}Oauth`] + if (!service) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `An OAuth handler for ${app.display_name} could not be found make sure the plugin is installed` + ) + } + + if (!(app.data.state === state)) { + throw new MedusaError( + MedusaError.Types.NOT_ALLOWED, + `${app.display_name} could not match state` + ) + } + + const authData = await service.generateToken(code) + + return await this.update(app.id, { + data: authData, + }).then(async (result) => { + await this.eventBus_.emit( + `${Oauth.Events.TOKEN_GENERATED}.${appName}`, + authData + ) + return result + }) + } + + async refreshToken(appName: string): Promise { + const app = await this.retrieveByName(appName) + const refreshToken = app.data.refresh_token + const service = this.container_[`${app.application_name}Oauth`] + if (!service) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `An OAuth handler for ${app.display_name} could not be found make sure the plugin is installed` + ) + } + + const authData = await service.refreshToken(refreshToken) + + return await this.update(app.id, { + data: authData, + }).then(async (result) => { + await this.eventBus_.emit( + `${Oauth.Events.TOKEN_REFRESHED}.${appName}`, + authData + ) + return result + }) + } +} + +export default Oauth diff --git a/packages/medusa/src/types/oauth.ts b/packages/medusa/src/types/oauth.ts new file mode 100644 index 0000000000..508660a837 --- /dev/null +++ b/packages/medusa/src/types/oauth.ts @@ -0,0 +1,10 @@ +export type CreateOauthInput = { + display_name: string + application_name: string + install_url?: string + uninstall_url?: string +} + +export type UpdateOauthInput = { + data: Record +}