Skip to content

Commit

Permalink
fix splitit oauth bug (#683)
Browse files Browse the repository at this point in the history
* generator changes

* more generator changes

* integration test
  • Loading branch information
eddiechayes authored Apr 11, 2024
1 parent 70fa803 commit 38a7c0b
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const setOAuthToObject = async function (object: any, name: string, scope
// Sets the OAuth2 authentication header for the request and saves the token for the next request
const authenticate = async () => {
if (configuration.oauthClientId && configuration.oauthClientSecret && configuration.accessToken === undefined) {
const token = await wrapAxiosRequest(async () => {
const tokenResponse = await wrapAxiosRequest(async () => {
{{#isAuthorizationOrTokenUrlRelative}}
if (configuration.basePath === undefined) {
throw new Error("basePath must be set to use the oauth2 authentication");
Expand Down Expand Up @@ -136,11 +136,12 @@ export const setOAuthToObject = async function (object: any, name: string, scope
}
return acc;
}, undefined);
return token
return {"token": token, "expires_in": json.expires_in };
})
if (token === undefined)
if (tokenResponse === undefined || tokenResponse.token === undefined)
throw new Error("Token not found in OAuth response")
configuration.accessToken = token
configuration.accessToken = tokenResponse.token
configuration.accessTokenExpiresIn = tokenResponse.expires_in !== undefined ? (Date.now() / 1000) + tokenResponse.expires_in : undefined
}
}
{{/-first}}
Expand All @@ -160,10 +161,17 @@ export const setOAuthToObject = async function (object: any, name: string, scope
await authenticate();
} else {
// check that the token is still valid
const decodedToken = jwtDecode(previousToken);
let decodedToken = undefined;
const currentTime = Date.now() / 1000;
if (decodedToken.exp !== undefined && decodedToken.exp < currentTime) {
await authenticate();
try { // If token is jwt
decodedToken = jwtDecode(previousToken);
} catch (e) {}
if (decodedToken !== undefined && decodedToken.exp !== undefined && decodedToken.exp < currentTime
|| configuration.accessTokenExpiresIn !== undefined && configuration.accessTokenExpiresIn < currentTime) {
configuration.accessToken = undefined;
configuration.accessTokenExpiresIn = undefined;
await authenticate();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ export class Configuration {
* @memberof Configuration
*/
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
/**
* When the access token expires, measured in Unix time in seconds
*/
accessTokenExpiresIn?: number;
/**
* override base path
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
index.test.ts
index.test.ts
client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ import { Configuration, ConfigurationParameters } from "./configuration";
import { TypescriptOauthTokenClientCustom } from "./client-custom";

export class TypescriptOauthTokenClient extends TypescriptOauthTokenClientCustom {
readonly test: TestApi;
test: TestApi;
config: Configuration;

constructor(configurationParameters: ConfigurationParameters) {
super(configurationParameters);
const configuration = new Configuration(configurationParameters);
this.test = new TestApi(configuration);
this.config = new Configuration(configurationParameters);
this.test = new TestApi(this.config);
}

setOauthTokenUrl(url: string) {
this.config.oauthTokenUrl = url;
this.test = new TestApi(this.config);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const setOAuthToObject = async function (object: any, name: string, scope
// Sets the OAuth2 authentication header for the request and saves the token for the next request
const authenticate = async () => {
if (configuration.oauthClientId && configuration.oauthClientSecret && configuration.accessToken === undefined) {
const token = await wrapAxiosRequest(async () => {
const tokenResponse = await wrapAxiosRequest(async () => {
const url = configuration.oauthTokenUrl ?? "http://127.0.0.1:4048/token"
const oauthResponse = await axios.request({
url,
Expand All @@ -128,11 +128,12 @@ export const setOAuthToObject = async function (object: any, name: string, scope
}
return acc;
}, undefined);
return token
return {"token": token, "expires_in": json.expires_in };
})
if (token === undefined)
if (tokenResponse === undefined || tokenResponse.token === undefined)
throw new Error("Token not found in OAuth response")
configuration.accessToken = token
configuration.accessToken = tokenResponse.token
configuration.accessTokenExpiresIn = tokenResponse.expires_in !== undefined ? (Date.now() / 1000) + tokenResponse.expires_in : undefined
}
}
const getToken = async () => {
Expand All @@ -149,10 +150,17 @@ export const setOAuthToObject = async function (object: any, name: string, scope
await authenticate();
} else {
// check that the token is still valid
const decodedToken = jwtDecode(previousToken);
let decodedToken = undefined;
const currentTime = Date.now() / 1000;
if (decodedToken.exp !== undefined && decodedToken.exp < currentTime) {
await authenticate();
try { // If token is jwt
decodedToken = jwtDecode(previousToken);
} catch (e) {}
if (decodedToken !== undefined && decodedToken.exp !== undefined && decodedToken.exp < currentTime
|| configuration.accessTokenExpiresIn !== undefined && configuration.accessTokenExpiresIn < currentTime) {

configuration.accessToken = undefined;
configuration.accessTokenExpiresIn = undefined;
await authenticate();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export class Configuration {
* @memberof Configuration
*/
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
/**
* When the access token expires, measured in Unix time in seconds
*/
accessTokenExpiresIn?: number;
/**
* override base path
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,27 @@ describe("typescript-oauth-token", () => {
const token = (result.data as any).headers.authorization;
expect(token).toBe("Bearer 1234567890");
});
it("token that expires", async () => {
const client = new TypescriptOauthTokenClient({
oauthClientId: "client_id",
oauthClientSecret: "client_secret",
basePath: "http://127.0.0.1:4048",
oauthTokenUrl: "http://127.0.0.1:4048/fast-expiring-token",
});
const result = await client.test.fetch();
const token = (result.data as any).headers.authorization;
expect(token).toBe("Bearer 0987654321");

client.setOauthTokenUrl("http://127.0.0.1:4048/token")

await new Promise((resolve) => setTimeout(resolve, 5000));
const result2 = await client.test.fetch();
const token2 = (result2.data as any).headers.authorization;
expect(token2).toBe("Bearer 0987654321"); // token should not have expired yet

await new Promise((resolve) => setTimeout(resolve, 5000));
const result3 = await client.test.fetch();
const token3 = (result3.data as any).headers.authorization;
expect(token3).toBe("Bearer 1234567890"); // token should have expired and been re-fetched
})
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ test("typescript-oauth-token", async () => {
expires_in: 3600,
},
},
{
path: "/fast-expiring-token",
method: "post",
response: {
access_token: "0987654321",
token_type: "Bearer",
expires_in: 10,
},
},
],
},
});
Expand Down

0 comments on commit 38a7c0b

Please sign in to comment.