Token being stored correctly in the secret store with refresh and expire info where relevant

This commit is contained in:
Matt Aitken
2023-04-25 14:08:28 +01:00
parent 01a4ff387f
commit 08abc86201
4 changed files with 44 additions and 20 deletions
@@ -191,16 +191,19 @@ export class APIAuthenticationRepository {
? process.env[authenticationMethod.config.appHostEnvName]
: env.APP_ORIGIN;
const token = await grantOAuth2Token({
const params = {
tokenUrl: authenticationMethod.config.token.url,
clientId: getClientConfig.id,
clientSecret: getClientConfig.secret,
code,
callbackUrl: `${callbackHostName}/resources/connection/oauth2/callback`,
scopes,
requestedScopes: scopes,
scopeSeparator:
authenticationMethod.config.authorization.scopeSeparator,
});
};
const token = await (authenticationMethod.config.token.grantToken
? authenticationMethod.config.token.grantToken(params)
: grantOAuth2Token(params));
console.log("token", token);
@@ -48,7 +48,7 @@ const slack: ExternalAPI = {
clientSecret,
code,
callbackUrl,
scopes,
requestedScopes,
}) => {
return grantOAuth2Token({
tokenUrl,
@@ -56,7 +56,7 @@ const slack: ExternalAPI = {
clientSecret,
code,
callbackUrl,
scopes,
requestedScopes,
scopeSeparator: " ",
});
},
@@ -78,16 +78,24 @@ export async function grantOAuth2Token({
clientSecret,
code,
callbackUrl,
scopes,
requestedScopes,
scopeSeparator,
accessTokenKey = "access_token",
refreshTokenKey = "refresh_token",
expiresAtKey = "expires_at",
scopeKey = "scope",
}: {
tokenUrl: string;
clientId: string;
clientSecret: string;
code: string;
callbackUrl: string;
scopes: string[];
requestedScopes: string[];
scopeSeparator: string;
accessTokenKey?: string;
refreshTokenKey?: string;
expiresAtKey?: string;
scopeKey?: string;
}): Promise<AccessToken> {
//create the oauth2 client
const tokenUrlObj = new URL(tokenUrl);
@@ -109,22 +117,29 @@ export async function grantOAuth2Token({
const token = await simpleOAuthClient.getToken({
code,
redirect_uri: callbackUrl,
scope: scopes.join(scopeSeparator),
scope: requestedScopes.join(scopeSeparator),
});
if (typeof token.token.access_token !== "string") {
const accessTokenValue = token.token[accessTokenKey];
if (typeof accessTokenValue !== "string") {
throw new Error("Invalid access token");
}
let actualScopes = scopes;
if (typeof token.token.scope === "string") {
actualScopes = token.token.scope.split(scopeSeparator);
let actualScopes = requestedScopes;
if (typeof token.token[scopeKey] === "string") {
actualScopes = (token.token[scopeKey] as string).split(scopeSeparator);
}
const refreshToken = token.token[refreshTokenKey] as string | undefined;
const expiresAt = token.token[expiresAtKey] as string | undefined;
const accessToken: AccessToken = {
type: "oauth2",
access_token: token.token.access_token,
accessToken: accessTokenValue,
refreshToken,
expiresAt,
scopes: actualScopes,
raw: token.token,
};
return accessToken;
+13 -7
View File
@@ -1,3 +1,5 @@
import { z } from "zod";
export type ExternalAPI = {
/** Used to uniquely identify an API */
identifier: string;
@@ -57,7 +59,7 @@ export type APIAuthenticationMethodOAuth2 = {
clientSecret: string;
code: string;
callbackUrl: string;
scopes: string[];
requestedScopes: string[];
}) => Promise<AccessToken>;
};
/** Refresh is how a token is refreshed */
@@ -89,10 +91,14 @@ type Scope = {
paramName?: string;
};
export type AccessToken = OAuth2AccessToken;
const OAuth2AccessTokenSchema = z.object({
type: z.literal("oauth2"),
accessToken: z.string(),
expiresAt: z.string().optional(),
refreshToken: z.string().optional(),
scopes: z.array(z.string()).optional(),
raw: z.any(),
});
type OAuth2AccessToken = {
type: "oauth2";
access_token: string;
scopes?: string[];
};
export const AccessTokenSchema = OAuth2AccessTokenSchema;
export type AccessToken = z.infer<typeof AccessTokenSchema>;