Skip to content

Commit e60fdc9

Browse files
Refactor rest api and manager services in spa (#2268)
* Refactor rest api and manager services in spa * fix test * clear token
1 parent d086e59 commit e60fdc9

14 files changed

Lines changed: 278 additions & 231 deletions

File tree

spa/src/api/apps/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { GetGitHubAppsUrlResponse } from "../../rest-interfaces/oauth-types";
2-
import { AxiosInstanceWithJWT } from "../axiosInstance";
3-
import { AxiosResponse } from "axios";
2+
import { axiosRest } from "../axiosInstance";
43

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

9-
export default GitHubApps;

spa/src/api/auth/index.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import { GetRedirectUrlResponse, ExchangeTokenResponse } from "../../rest-interfaces/oauth-types";
2-
import { AxiosInstanceWithJWT } from "../axiosInstance";
3-
import { AxiosResponse } from "axios";
2+
import { axiosRest } from "../axiosInstance";
43

5-
const GitHubAuth = {
6-
generateOAuthUrl: (): Promise<AxiosResponse<GetRedirectUrlResponse>> => AxiosInstanceWithJWT.get("/rest/app/cloud/oauth/redirectUrl"),
7-
exchangeToken: (code: string, state: string): Promise<AxiosResponse<ExchangeTokenResponse>> =>
8-
AxiosInstanceWithJWT.post<ExchangeTokenResponse>("/rest/app/cloud/oauth/exchangeToken", { code, state })
4+
export default {
5+
generateOAuthUrl: () => axiosRest.get<GetRedirectUrlResponse>("/rest/app/cloud/oauth/redirectUrl"),
6+
exchangeToken: (code: string, state: string) => axiosRest.post<ExchangeTokenResponse>("/rest/app/cloud/oauth/exchangeToken", { code, state }),
97
};
10-
11-
export default GitHubAuth;

spa/src/api/axiosInstance.ts

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,60 @@ const getHeaders = (): Promise<string> => new Promise(resolve => {
66
});
77
});
88

9-
const AxiosInstanceWithJWT = axios.create({
9+
const axiosRest = axios.create({
1010
timeout: 3000
1111
});
12-
1312
// Adding the token in the headers through interceptors because it is an async value
14-
AxiosInstanceWithJWT.interceptors.request.use(async (config) => {
13+
axiosRest.interceptors.request.use(async (config) => {
1514
config.headers.Authorization = await getHeaders();
1615
return config;
1716
});
1817

19-
const AxiosInstanceWithGHToken = async (gitHubToken: string) => axios.create({
20-
timeout: 3000,
21-
headers: {
22-
"github-auth": gitHubToken,
23-
Authorization: await getHeaders()
18+
/*
19+
* IMPORTANT
20+
* This is a secret store of the github access token
21+
* DO NOT export/exposed this store
22+
* Only write operation is allowed
23+
*/
24+
let gitHubToken: string | undefined = undefined;
25+
26+
const clearGitHubToken = () => {
27+
gitHubToken = undefined;
28+
}
29+
30+
const setGitHubToken = (newToken: string) => {
31+
gitHubToken = newToken;
32+
}
33+
34+
const hasGitHubToken = () => {
35+
if (!!gitHubToken) {
36+
return true;
2437
}
38+
return false;
39+
}
40+
41+
const axiosGitHub = axios.create({
42+
timeout: 3000
43+
});
44+
axiosGitHub.interceptors.request.use(async (config) => {
45+
config.headers["Authorization"] = `Bearer ${gitHubToken}`;
46+
return config;
47+
});
48+
49+
const axiosRestWithGitHubToken = axios.create({
50+
timeout: 3000
51+
});
52+
axiosRestWithGitHubToken.interceptors.request.use(async (config) => {
53+
config.headers.Authorization = await getHeaders();
54+
config.headers["github-auth"] = gitHubToken;
55+
return config;
2556
});
2657

2758
export {
28-
AxiosInstanceWithJWT,
29-
AxiosInstanceWithGHToken
59+
axiosGitHub,
60+
axiosRest,
61+
axiosRestWithGitHubToken,
62+
clearGitHubToken,
63+
setGitHubToken,
64+
hasGitHubToken,
3065
};

spa/src/api/github/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { UsersGetAuthenticatedResponse } from "../../rest-interfaces/oauth-types";
2+
import { axiosGitHub } from "../axiosInstance";
3+
4+
export default {
5+
getUserDetails: () => axiosGitHub.get<UsersGetAuthenticatedResponse>("https://api.github.com/user"),
6+
};

spa/src/api/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import Token from "./token";
2-
import GitHubAuth from "./auth";
3-
import GitHubApps from "./apps";
2+
import Auth from "./auth";
3+
import App from "./apps";
4+
import Orgs from "./orgs";
5+
import GitHub from "./github";
46

57
const ApiRequest = {
68
token: Token,
7-
githubAuth: GitHubAuth,
8-
gitHubApp: GitHubApps,
9+
auth: Auth,
10+
gitHub: GitHub,
11+
app: App,
12+
orgs: Orgs
913
};
1014

1115
export default ApiRequest;

spa/src/api/orgs/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { OrganizationsResponse } from "../../rest-interfaces/oauth-types";
2+
import { axiosRestWithGitHubToken } from "../axiosInstance";
3+
4+
export default {
5+
getOrganizations: async () => axiosRestWithGitHubToken.get<OrganizationsResponse>("/rest/app/cloud/org"),
6+
connectOrganization: async (orgId: number) => axiosRestWithGitHubToken.post<OrganizationsResponse>("/rest/app/cloud/org", { installationId: orgId }),
7+
};

spa/src/api/token/index.ts

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,7 @@
1-
import axios, { AxiosResponse } from "axios";
2-
import { OrganizationsResponse, UsersGetAuthenticatedResponse } from "../../rest-interfaces/oauth-types";
3-
import { AxiosInstanceWithGHToken } from "../axiosInstance";
1+
import { clearGitHubToken, setGitHubToken, hasGitHubToken } from "../axiosInstance";
42

5-
const Token = {
6-
getUserDetails: (token: string): Promise<AxiosResponse<UsersGetAuthenticatedResponse>> => axios.get("https://api.github.com/user", {
7-
headers: { Authorization: `Bearer ${token}`}
8-
}),
9-
getOrganizations: async (token: string): Promise<AxiosResponse<OrganizationsResponse>> => {
10-
const instance = await AxiosInstanceWithGHToken(token);
11-
return instance.get("/rest/app/cloud/org");
12-
},
13-
connectOrganization: async (token: string, orgId: number): Promise<AxiosResponse<OrganizationsResponse>> => {
14-
const instance = await AxiosInstanceWithGHToken(token);
15-
return instance.post("/rest/app/cloud/org", { installationId: orgId });
16-
},
3+
export default {
4+
hasGitHubToken,
5+
clearGitHubToken,
6+
setGitHubToken,
177
};
18-
19-
export default Token;

spa/src/global.d.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { OrganizationsResponse } from "./rest-interfaces/oauth-types.ts";
22

33
declare global {
4-
let OAuthManagerInstance: OAuthManagerType;
54
const AP: AtlassianPlugin;
65
}
76

@@ -16,13 +15,3 @@ interface AtlassianPlugin {
1615
}
1716
}
1817

19-
export interface OAuthManagerType {
20-
checkValidity: () => Promise<boolean | undefined>;
21-
fetchOrgs: () => Promise<OrganizationsResponse | undefined>;
22-
connectOrg: (orgId: number) => Promise<boolean | undefined>;
23-
authenticateInGitHub: () => Promise<void>;
24-
finishOAuthFlow: (code: string, state: string) => Promise<boolean>;
25-
getUserDetails: () => { username: string | undefined, email: string | undefined };
26-
clear: () => void;
27-
installNewApp: (onFinish: () => void) => Promise<void>;
28-
}

spa/src/index.tsx

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,12 @@ import {
77
Route,
88
Routes,
99
} from "react-router-dom";
10-
import OauthManager from "./oauth-manager";
1110
import StartConnection from "./pages/StartConnection";
1211
import ConfigSteps from "./pages/ConfigSteps";
1312
import Connected from "./pages/Connected";
1413

15-
/**
16-
* This is the global variable for handling Auth related methods
17-
*/
18-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
19-
// @ts-ignore
20-
globalThis.OAuthManagerInstance = OauthManager();
21-
2214
const App = () => {
15+
2316
setGlobalTheme({
2417
light: "light",
2518
dark: "dark",

spa/src/oauth-manager/index.tsx

Lines changed: 0 additions & 128 deletions
This file was deleted.

0 commit comments

Comments
 (0)