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