fix(medusa-plugin-brightpearl): reliable oauth (#119)
This commit is contained in:
1 parent
a06d603722
commit
0889059ba1
5 files changed
+37
-41
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({
|
||||||
access_token: "good",
|
data: {
|
||||||
|
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 () => {
|
||||||
account: this.options.account,
|
const appData = await this.oauthService_.retrieveByName("brightpearl")
|
||||||
url: data.api_domain,
|
const authenticationData = appData.data
|
||||||
auth_type: data.token_type,
|
return authenticationData.access_token
|
||||||
access_token: data.access_token,
|
|
||||||
},
|
},
|
||||||
async (client) => {
|
refreshToken: async () => {
|
||||||
const newAuth = await this.oauthService_.refreshToken(
|
const newAuthentication = await this.oauthService_.refreshToken(
|
||||||
"brightpearl",
|
"brightpearl"
|
||||||
data.refresh_token
|
|
||||||
)
|
)
|
||||||
client.updateAuth({
|
return newAuthentication.data.refresh_token
|
||||||
auth_type: newAuth.token_type,
|
},
|
||||||
access_token: newAuth.access_token,
|
}
|
||||||
})
|
|
||||||
}
|
const client = new Brightpearl({
|
||||||
)
|
account: this.options.account,
|
||||||
|
url: data.api_domain,
|
||||||
|
token_store: tokenStore,
|
||||||
|
})
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in new issue
Block a user