Skip to content

Commit

Permalink
Refactor rest api and manager services in spa (#2268)
Browse files Browse the repository at this point in the history
* Refactor rest api and manager services in spa

* fix test

* clear token
  • Loading branch information
gxueatlassian authored Jul 21, 2023
1 parent d086e59 commit e60fdc9
Show file tree
Hide file tree
Showing 14 changed files with 278 additions and 231 deletions.
8 changes: 3 additions & 5 deletions spa/src/api/apps/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { GetGitHubAppsUrlResponse } from "../../rest-interfaces/oauth-types";
import { AxiosInstanceWithJWT } from "../axiosInstance";
import { AxiosResponse } from "axios";
import { axiosRest } from "../axiosInstance";

const GitHubApps = {
getAppNewInstallationUrl: (): Promise<AxiosResponse<GetGitHubAppsUrlResponse>> => AxiosInstanceWithJWT.get("/rest/app/cloud/installation/new"),
export default {
getAppNewInstallationUrl: () => axiosRest.get<GetGitHubAppsUrlResponse>("/rest/app/cloud/installation/new"),
};

export default GitHubApps;
12 changes: 4 additions & 8 deletions spa/src/api/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { GetRedirectUrlResponse, ExchangeTokenResponse } from "../../rest-interfaces/oauth-types";
import { AxiosInstanceWithJWT } from "../axiosInstance";
import { AxiosResponse } from "axios";
import { axiosRest } from "../axiosInstance";

const GitHubAuth = {
generateOAuthUrl: (): Promise<AxiosResponse<GetRedirectUrlResponse>> => AxiosInstanceWithJWT.get("/rest/app/cloud/oauth/redirectUrl"),
exchangeToken: (code: string, state: string): Promise<AxiosResponse<ExchangeTokenResponse>> =>
AxiosInstanceWithJWT.post<ExchangeTokenResponse>("/rest/app/cloud/oauth/exchangeToken", { code, state })
export default {
generateOAuthUrl: () => axiosRest.get<GetRedirectUrlResponse>("/rest/app/cloud/oauth/redirectUrl"),
exchangeToken: (code: string, state: string) => axiosRest.post<ExchangeTokenResponse>("/rest/app/cloud/oauth/exchangeToken", { code, state }),
};

export default GitHubAuth;
55 changes: 45 additions & 10 deletions spa/src/api/axiosInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,60 @@ const getHeaders = (): Promise<string> => new Promise(resolve => {
});
});

const AxiosInstanceWithJWT = axios.create({
const axiosRest = axios.create({
timeout: 3000
});

// Adding the token in the headers through interceptors because it is an async value
AxiosInstanceWithJWT.interceptors.request.use(async (config) => {
axiosRest.interceptors.request.use(async (config) => {
config.headers.Authorization = await getHeaders();
return config;
});

const AxiosInstanceWithGHToken = async (gitHubToken: string) => axios.create({
timeout: 3000,
headers: {
"github-auth": gitHubToken,
Authorization: await getHeaders()
/*
* IMPORTANT
* This is a secret store of the github access token
* DO NOT export/exposed this store
* Only write operation is allowed
*/
let gitHubToken: string | undefined = undefined;

const clearGitHubToken = () => {
gitHubToken = undefined;
}

const setGitHubToken = (newToken: string) => {
gitHubToken = newToken;
}

const hasGitHubToken = () => {
if (!!gitHubToken) {
return true;
}
return false;
}

const axiosGitHub = axios.create({
timeout: 3000
});
axiosGitHub.interceptors.request.use(async (config) => {
config.headers["Authorization"] = `Bearer ${gitHubToken}`;
return config;
});

const axiosRestWithGitHubToken = axios.create({
timeout: 3000
});
axiosRestWithGitHubToken.interceptors.request.use(async (config) => {
config.headers.Authorization = await getHeaders();
config.headers["github-auth"] = gitHubToken;
return config;
});

export {
AxiosInstanceWithJWT,
AxiosInstanceWithGHToken
axiosGitHub,
axiosRest,
axiosRestWithGitHubToken,
clearGitHubToken,
setGitHubToken,
hasGitHubToken,
};
6 changes: 6 additions & 0 deletions spa/src/api/github/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { UsersGetAuthenticatedResponse } from "../../rest-interfaces/oauth-types";
import { axiosGitHub } from "../axiosInstance";

export default {
getUserDetails: () => axiosGitHub.get<UsersGetAuthenticatedResponse>("https://api.github.com/user"),
};
12 changes: 8 additions & 4 deletions spa/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import Token from "./token";
import GitHubAuth from "./auth";
import GitHubApps from "./apps";
import Auth from "./auth";
import App from "./apps";
import Orgs from "./orgs";
import GitHub from "./github";

const ApiRequest = {
token: Token,
githubAuth: GitHubAuth,
gitHubApp: GitHubApps,
auth: Auth,
gitHub: GitHub,
app: App,
orgs: Orgs
};

export default ApiRequest;
7 changes: 7 additions & 0 deletions spa/src/api/orgs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { OrganizationsResponse } from "../../rest-interfaces/oauth-types";
import { axiosRestWithGitHubToken } from "../axiosInstance";

export default {
getOrganizations: async () => axiosRestWithGitHubToken.get<OrganizationsResponse>("/rest/app/cloud/org"),
connectOrganization: async (orgId: number) => axiosRestWithGitHubToken.post<OrganizationsResponse>("/rest/app/cloud/org", { installationId: orgId }),
};
22 changes: 5 additions & 17 deletions spa/src/api/token/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
import axios, { AxiosResponse } from "axios";
import { OrganizationsResponse, UsersGetAuthenticatedResponse } from "../../rest-interfaces/oauth-types";
import { AxiosInstanceWithGHToken } from "../axiosInstance";
import { clearGitHubToken, setGitHubToken, hasGitHubToken } from "../axiosInstance";

const Token = {
getUserDetails: (token: string): Promise<AxiosResponse<UsersGetAuthenticatedResponse>> => axios.get("https://api.github.com/user", {
headers: { Authorization: `Bearer ${token}`}
}),
getOrganizations: async (token: string): Promise<AxiosResponse<OrganizationsResponse>> => {
const instance = await AxiosInstanceWithGHToken(token);
return instance.get("/rest/app/cloud/org");
},
connectOrganization: async (token: string, orgId: number): Promise<AxiosResponse<OrganizationsResponse>> => {
const instance = await AxiosInstanceWithGHToken(token);
return instance.post("/rest/app/cloud/org", { installationId: orgId });
},
export default {
hasGitHubToken,
clearGitHubToken,
setGitHubToken,
};

export default Token;
11 changes: 0 additions & 11 deletions spa/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { OrganizationsResponse } from "./rest-interfaces/oauth-types.ts";

declare global {
let OAuthManagerInstance: OAuthManagerType;
const AP: AtlassianPlugin;
}

Expand All @@ -16,13 +15,3 @@ interface AtlassianPlugin {
}
}

export interface OAuthManagerType {
checkValidity: () => Promise<boolean | undefined>;
fetchOrgs: () => Promise<OrganizationsResponse | undefined>;
connectOrg: (orgId: number) => Promise<boolean | undefined>;
authenticateInGitHub: () => Promise<void>;
finishOAuthFlow: (code: string, state: string) => Promise<boolean>;
getUserDetails: () => { username: string | undefined, email: string | undefined };
clear: () => void;
installNewApp: (onFinish: () => void) => Promise<void>;
}
9 changes: 1 addition & 8 deletions spa/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,12 @@ import {
Route,
Routes,
} from "react-router-dom";
import OauthManager from "./oauth-manager";
import StartConnection from "./pages/StartConnection";
import ConfigSteps from "./pages/ConfigSteps";
import Connected from "./pages/Connected";

/**
* This is the global variable for handling Auth related methods
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
globalThis.OAuthManagerInstance = OauthManager();

const App = () => {

setGlobalTheme({
light: "light",
dark: "dark",
Expand Down
128 changes: 0 additions & 128 deletions spa/src/oauth-manager/index.tsx

This file was deleted.

Loading

0 comments on commit e60fdc9

Please sign in to comment.