Skip to content

Commit

Permalink
feat(sdk-middleware-auth): add request timeout for sdk-middleware-auth (
Browse files Browse the repository at this point in the history
  • Loading branch information
ajimae authored Nov 4, 2021
1 parent 1167644 commit 8faa5de
Show file tree
Hide file tree
Showing 14 changed files with 457 additions and 141 deletions.
55 changes: 43 additions & 12 deletions integration-tests/cli/personal-data-erasure.it.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,49 @@ describe('personal data erasure', () => {
const data = await personalDataErasure.getCustomerData(customerId)

expect(data).toHaveLength(11)
expect(data).toContainEqual(expect.objectContaining({type: 'CartCreated'}))
expect(data).toContainEqual(expect.objectContaining({type: 'PaymentCreated'}))
expect(data).toContainEqual(expect.objectContaining({type: 'CustomerCreated'}))
expect(data).toContainEqual(expect.objectContaining({type: 'ReviewCreated'}))
expect(data).toContainEqual(expect.objectContaining({type: 'OrderCreated'}))
expect(data).toContainEqual(expect.objectContaining({type: 'CartCreated'}))
expect(data).toContainEqual(expect.objectContaining({type: 'Order'}))
expect(data).toContainEqual(expect.objectContaining({type: 'Cart'}))
expect(data).toContainEqual(expect.objectContaining({email: 'foo@bar.de'}))
expect(data).toContainEqual(expect.objectContaining({amountPlanned: { type: 'centPrecision', currencyCode: 'EUR', centAmount: 100, fractionDigits: 2}}))
expect(data).toContainEqual(expect.objectContaining({name: {de: 'deutscherListenName', en: 'englishListName'}}))
expect(data).toContainEqual(expect.objectContaining({text: 'Review text'}))
expect(data).toContainEqual(
expect.objectContaining({ type: 'CartCreated' })
)
expect(data).toContainEqual(
expect.objectContaining({ type: 'PaymentCreated' })
)
expect(data).toContainEqual(
expect.objectContaining({ type: 'CustomerCreated' })
)
expect(data).toContainEqual(
expect.objectContaining({ type: 'ReviewCreated' })
)
expect(data).toContainEqual(
expect.objectContaining({ type: 'OrderCreated' })
)
expect(data).toContainEqual(
expect.objectContaining({ type: 'CartCreated' })
)
expect(data).toContainEqual(
expect.objectContaining({ type: 'Order' })
)
expect(data).toContainEqual(expect.objectContaining({ type: 'Cart' }))
expect(data).toContainEqual(
expect.objectContaining({ email: 'foo@bar.de' })
)
expect(data).toContainEqual(
expect.objectContaining({
amountPlanned: {
type: 'centPrecision',
currencyCode: 'EUR',
centAmount: 100,
fractionDigits: 2,
},
})
)
expect(data).toContainEqual(
expect.objectContaining({
name: { de: 'deutscherListenName', en: 'englishListName' },
})
)
expect(data).toContainEqual(
expect.objectContaining({ text: 'Review text' })
)
})
})

Expand Down
4 changes: 1 addition & 3 deletions integration-tests/sdk/auth-middleware.it.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,7 @@ describe('Auth Middleware Flows', () => {
({
body: { results: carts },
request: {
headers: {
Authorization: token,
},
headers: { Authorization: token },
},
}) => {
// Assert that a different token was used to fetch the carts
Expand Down
61 changes: 29 additions & 32 deletions integration-tests/sdk/auth.it.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,39 +288,36 @@ describe('Auth Flows', () => {
})

it('should tokenProvider work even after changing fetchTokenInfo funtion', async () => {
const onTokenInfoRefreshedMock = jest.fn()

const tokenProvider = new TokenProvider(
{
sdkAuth: authClient,
onTokenInfoRefreshed: onTokenInfoRefreshedMock,
}
)
tokenProvider.fetchTokenInfo = (sdkAuth) =>
sdkAuth.refreshTokenFlow(encodeURIComponent("invalid refresh token"));

try {
await tokenProvider.getAccessToken()
} catch (err) {
expect(err.toString()).toEqual(
expect.stringContaining(
'BadRequest: The refresh token was not found. It may have expired.'
)
)
tokenProvider.fetchTokenInfo = (sdkAuth) =>
sdkAuth.anonymousFlow();
const tokenInfo = await tokenProvider.getTokenInfo();

// check returned properties
expect(tokenInfo).toHaveProperty('access_token')
expect(tokenInfo.scope).toMatch(
`manage_project:${projectKey} anonymous_id`
const onTokenInfoRefreshedMock = jest.fn()

const tokenProvider = new TokenProvider({
sdkAuth: authClient,
onTokenInfoRefreshed: onTokenInfoRefreshedMock,
})
tokenProvider.fetchTokenInfo = (sdkAuth) =>
sdkAuth.refreshTokenFlow(encodeURIComponent('invalid refresh token'))

try {
await tokenProvider.getAccessToken()
} catch (err) {
expect(err.toString()).toEqual(
expect.stringContaining(
'BadRequest: The refresh token was not found. It may have expired.'
)
expect(tokenInfo).toHaveProperty('expires_in')
expect(tokenInfo).toHaveProperty('expires_at')
expect(tokenInfo).toHaveProperty('refresh_token')
expect(tokenInfo).toHaveProperty('token_type', 'Bearer')
}
)
tokenProvider.fetchTokenInfo = (sdkAuth) => sdkAuth.anonymousFlow()
const tokenInfo = await tokenProvider.getTokenInfo()

// check returned properties
expect(tokenInfo).toHaveProperty('access_token')
expect(tokenInfo.scope).toMatch(
`manage_project:${projectKey} anonymous_id`
)
expect(tokenInfo).toHaveProperty('expires_in')
expect(tokenInfo).toHaveProperty('expires_at')
expect(tokenInfo).toHaveProperty('refresh_token')
expect(tokenInfo).toHaveProperty('token_type', 'Bearer')
}
})
})

Expand Down
32 changes: 18 additions & 14 deletions packages/sdk-auth/src/tokenProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,15 @@ export default class TokenProvider {
this.fetchTokenInfo(this.sdkAuth)
)

return this.fetchTokenInfoPromise.then((tokenInfo) => {
this.fetchTokenInfoPromise = null
return tokenInfo
}).catch((error) => {
return this.fetchTokenInfoPromise
.then((tokenInfo) => {
this.fetchTokenInfoPromise = null
return tokenInfo
})
.catch((error) => {
this.fetchTokenInfoPromise = null
throw error
})
})
}

_performRefreshTokenFlow(refreshToken: string): Promise<TokenInfo> {
Expand All @@ -91,34 +93,36 @@ export default class TokenProvider {

this.refreshTokenFlowPromise = this.sdkAuth.refreshTokenFlow(refreshToken)

return this.refreshTokenFlowPromise.then((refreshTokenInfo) => {
this.refreshTokenFlowPromise = null
return refreshTokenInfo
}).catch((error) => {
this.refreshTokenFlowPromise = null;
return this.refreshTokenFlowPromise
.then((refreshTokenInfo) => {
this.refreshTokenFlowPromise = null
return refreshTokenInfo
})
.catch((error) => {
this.refreshTokenFlowPromise = null
throw error
})
})
}

_refreshToken(oldTokenInfo: TokenInfo): Promise<TokenInfo> {
let newTokenInfo

if (!oldTokenInfo?.['refresh_token'] && !this.fetchTokenInfo)
if (!oldTokenInfo?.refresh_token && !this.fetchTokenInfo)
return Promise.reject(
new Error(
'Property "refresh_token" and "fetchTokenInfo" method are missing'
)
)

// perform refreshTokenFlow if we have refresh token otherwise call getTokenInfo method
const newTokenPromise = oldTokenInfo?.['refresh_token']
const newTokenPromise = oldTokenInfo?.refresh_token
? this._performRefreshTokenFlow(oldTokenInfo.refresh_token)
: this._performFetchTokenInfo()

return newTokenPromise
.then((tokenInfo: TokenInfo): void => {
newTokenInfo = tokenInfo
if (oldTokenInfo?.['refresh_token'])
if (oldTokenInfo?.refresh_token)
newTokenInfo.refresh_token = oldTokenInfo.refresh_token
return this.onTokenInfoRefreshed?.(newTokenInfo, oldTokenInfo)
})
Expand Down
48 changes: 24 additions & 24 deletions packages/sdk-auth/test/token-provider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,32 +42,32 @@ describe('Token Provider', () => {
})

test('should clear cache after _performFetchTokenInfo rejects', async () => {
const _tokenProvider = new TokenProvider({
sdkAuth,
fetchTokenInfo: jest
.fn()
.mockImplementation(() => Promise.reject(new Error("Invalid Token"))),
})
expect(_tokenProvider.fetchTokenInfoPromise).toBeFalsy();
try {
await _tokenProvider._performFetchTokenInfo()
} catch(e) {
expect(_tokenProvider.fetchTokenInfoPromise).toBeFalsy();
}
const _tokenProvider = new TokenProvider({
sdkAuth,
fetchTokenInfo: jest
.fn()
.mockImplementation(() => Promise.reject(new Error('Invalid Token'))),
})
expect(_tokenProvider.fetchTokenInfoPromise).toBeFalsy()
try {
await _tokenProvider._performFetchTokenInfo()
} catch (e) {
expect(_tokenProvider.fetchTokenInfoPromise).toBeFalsy()
}
})
test('should clear cache after _performRefreshTokenFlow rejects', async () => {
const _tokenProvider = new TokenProvider({
sdkAuth,
fetchTokenInfo: jest
.fn()
.mockImplementation(() => Promise.reject(new Error("Invalid Token"))),
})
expect(_tokenProvider.refreshTokenFlowPromise).toBeFalsy();
try {
await _tokenProvider._performRefreshTokenFlow("invalid refresh token")
} catch(e) {
expect(_tokenProvider.refreshTokenFlowPromise).toBeFalsy();
}
const _tokenProvider = new TokenProvider({
sdkAuth,
fetchTokenInfo: jest
.fn()
.mockImplementation(() => Promise.reject(new Error('Invalid Token'))),
})
expect(_tokenProvider.refreshTokenFlowPromise).toBeFalsy()
try {
await _tokenProvider._performRefreshTokenFlow('invalid refresh token')
} catch (e) {
expect(_tokenProvider.refreshTokenFlowPromise).toBeFalsy()
}
})

test('should throw an error when refreshing without "refresh_token" property', async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/sdk-middleware-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"node-fetch": "^2.3.0"
},
"devDependencies": {
"abort-controller": "^3.0.0",
"nock": "12.0.3"
}
}
1 change: 1 addition & 0 deletions packages/sdk-middleware-auth/src/anonymous-session-flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default function createAuthMiddlewareForAnonymousSessionFlow(
return
}
const params = {
...options,
request,
response,
...buildRequestForAnonymousSessionFlow(options),
Expand Down
Loading

0 comments on commit 8faa5de

Please sign in to comment.