fix(medusa-plugin-brightpearl): reliable oauth (#119)

This commit is contained in:
Sebastian Rindom authored and GitHub committed 2020-10-05 11:48:20 +02:00
1 parent a06d603722
commit 0889059ba1
5 files changed
+35 -39

No files matched your search

@@ -49,16 +49,20 @@ const RegionService = {
describe("BrightpearlService", () => { describe("BrightpearlService", () => {
describe("getClient", () => { describe("getClient", () => {
it("creates client", async () => { it("creates client", async () => {
let token = "bad"
const oauth = { const oauth = {
refreshToken: () => { refreshToken: () => {
token = "good"
return Promise.resolve({ return Promise.resolve({
data: {
access_token: "good", access_token: "good",
},
}) })
}, },
retrieveByName: () => { retrieveByName: () => {
return Promise.resolve({ return Promise.resolve({
data: { data: {
access_token: "bad", access_token: token,
}, },
}) })
}, },
@@ -36,24 +36,25 @@ class BrightpearlService extends BaseService {
) )
} }
const client = new Brightpearl( const tokenStore = {
{ getToken: async () => {
const appData = await this.oauthService_.retrieveByName("brightpearl")
const authenticationData = appData.data
return authenticationData.access_token
},
refreshToken: async () => {
const newAuthentication = await this.oauthService_.refreshToken(
"brightpearl"
)
return newAuthentication.data.refresh_token
},
}
const client = new Brightpearl({
account: this.options.account, account: this.options.account,
url: data.api_domain, url: data.api_domain,
auth_type: data.token_type, token_store: tokenStore,
access_token: data.access_token,
},
async (client) => {
const newAuth = await this.oauthService_.refreshToken(
"brightpearl",
data.refresh_token
)
client.updateAuth({
auth_type: newAuth.token_type,
access_token: newAuth.access_token,
}) })
}
)
this.authData_ = data this.authData_ = data
return client return client
@@ -3,7 +3,8 @@ export const mockCreateOrder = jest
.fn() .fn()
.mockReturnValue(Promise.resolve("1234")) .mockReturnValue(Promise.resolve("1234"))
const mock = jest.fn().mockImplementation(function (options, onRefresh) { const mock = jest.fn().mockImplementation(function (options) {
this.tokenStore_ = options.token_store
this.token_ = options.access_token this.token_ = options.access_token
this.client = axios.create({ this.client = axios.create({
baseURL: `https://mock.com`, baseURL: `https://mock.com`,
@@ -17,8 +18,8 @@ const mock = jest.fn().mockImplementation(function (options, onRefresh) {
this.token_ = data.access_token this.token_ = data.access_token
} }
this.client.interceptors.request.use((request) => { this.client.interceptors.request.use(async (request) => {
const token = this.token_ const token = await this.tokenStore_.getToken()
if (token) { if (token) {
request.headers["Authorization"] = `Bearer ${token}` request.headers["Authorization"] = `Bearer ${token}`
@@ -37,7 +38,7 @@ const mock = jest.fn().mockImplementation(function (options, onRefresh) {
!error.config.__isRetryRequest !error.config.__isRetryRequest
) { ) {
try { try {
await onRefresh(this) await this.tokenStore_.refreshToken()
} catch (authError) { } catch (authError) {
// refreshing has failed, but report the original error, i.e. 401 // refreshing has failed, but report the original error, i.e. 401
return Promise.reject(error) return Promise.reject(error)
@@ -48,7 +48,7 @@ class BrightpearlClient {
}) })
} }
constructor(options, onRefreshToken) { constructor(options) {
this.client_ = rateLimit( this.client_ = rateLimit(
axios.create({ axios.create({
baseURL: `https://${options.url}/public-api/${options.account}`, baseURL: `https://${options.url}/public-api/${options.account}`,
@@ -60,8 +60,8 @@ class BrightpearlClient {
{ maxRequests: RATE_LIMIT_REQUESTS, perMilliseconds: RATE_LIMIT_INTERVAL } { maxRequests: RATE_LIMIT_REQUESTS, perMilliseconds: RATE_LIMIT_INTERVAL }
) )
this.tokenStore_ = options.token_store
this.authType_ = options.auth_type this.authType_ = options.auth_type
this.token_ = options.access_token
this.webhooks = this.buildWebhookEndpoints() this.webhooks = this.buildWebhookEndpoints()
this.payments = this.buildPaymentEndpoints() this.payments = this.buildPaymentEndpoints()
this.warehouses = this.buildWarehouseEndpoints() this.warehouses = this.buildWarehouseEndpoints()
@@ -70,23 +70,12 @@ class BrightpearlClient {
this.customers = this.buildCustomerEndpoints() this.customers = this.buildCustomerEndpoints()
this.products = this.buildProductEndpoints() this.products = this.buildProductEndpoints()
this.buildRefreshTokenInterceptor_(onRefreshToken) this.buildRefreshTokenInterceptor_()
} }
updateAuth(data) { buildRefreshTokenInterceptor_() {
if (data.auth_type) { this.client_.interceptors.request.use(async (request) => {
this.authType_ = data.auth_type const token = await this.tokenStore_.getToken()
}
if (data.access_token) {
this.token_ = data.access_token
}
}
buildRefreshTokenInterceptor_(onRefresh) {
this.client_.interceptors.request.use((request) => {
const authType = this.authType_
const token = this.token_
if (token) { if (token) {
request.headers["Authorization"] = `Bearer ${token}` request.headers["Authorization"] = `Bearer ${token}`
@@ -105,7 +94,7 @@ class BrightpearlClient {
!error.config.__isRetryRequest !error.config.__isRetryRequest
) { ) {
try { try {
await onRefresh(this) await this.tokenStore_.refreshToken()
} catch (authError) { } catch (authError) {
// refreshing has failed, but report the original error, i.e. 401 // refreshing has failed, but report the original error, i.e. 401
return Promise.reject(error) return Promise.reject(error)
+2 -1
View File
@@ -83,8 +83,9 @@ class Oauth extends OauthService {
}) })
} }
async refreshToken(appName, refreshToken) { async refreshToken(appName) {
const app = await this.retrieveByName(appName) const app = await this.retrieveByName(appName)
const refreshToken = app.data.refresh_token
const service = this.container_[`${app.application_name}Oauth`] const service = this.container_[`${app.application_name}Oauth`]
if (!service) { if (!service) {
throw new MedusaError( throw new MedusaError(