Skip to content

Commit

Permalink
Merge branch 'main' into jira-admin-check-ff-remove
Browse files Browse the repository at this point in the history
  • Loading branch information
joshkay10 authored Oct 30, 2023
2 parents 927bc9e + 8307217 commit bb7d683
Show file tree
Hide file tree
Showing 45 changed files with 1,740 additions and 1,222 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14.21.1
18.18.1
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Please note that this project has a [Contributor Code of Conduct](CODE_OF_CONDUC

## Getting Started

This app is written in [Typescript](https://www.typescriptlang.org/) and runs on [Node.js](https://nodejs.org/) **v14.x**.
This app is written in [Typescript](https://www.typescriptlang.org/) and runs on [Node.js](https://nodejs.org/) **v18.x**.

Please install [Docker](https://www.docker.com/get-started) and [Docker Compose](https://docs.docker.com/compose/install/) to easily run the project locally.

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:14.21-alpine3.16 as build
FROM node:18-alpine3.18 as build

# adding python for node-gyp
RUN apk add g++ make python3
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:14.21-alpine3.16 as build
FROM node:18-alpine3.18 as build

# adding python for node-gyp
RUN apk add g++ make python3
Expand Down Expand Up @@ -28,7 +28,7 @@ RUN yarn run build:release
# https://stackoverflow.com/questions/57108751/docker-build-failed-when-copying-in-multi-step-build
RUN chown root:root -R /app

FROM node:14.21-alpine3.16
FROM node:18-alpine3.18

# adding to solve vuln
RUN apk add --update --upgrade busybox
Expand Down
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "GitHub integration for Atlassian Jira",
"repository": "https://github.com/atlassian/github-for-jira.git",
"engines": {
"node": ">= 14.21 <15",
"node": ">= 18.18.1",
"yarn": "^1.22.0"
},
"main": "src/main",
Expand All @@ -28,7 +28,7 @@
"lint:ts": "eslint . --ext .ts,.tsx",
"lint:yaml": "yamllint github-for-jira.sd.yml",
"pretest": "NODE_ENV=test run-p clean setup db:test",
"test": "yarn spa:test && jest --runInBand --forceExit --coverage",
"test": "yarn spa:test && jest --forceExit --coverage --runInBand --logHeapUsage --workerIdleMemoryLimit='2GB'",
"test:watch": "jest --runInBand --watchAll --coverage=false",
"db": "run-s db:create db:migrate",
"db:create": "run-p db:create:dev db:create:test",
Expand Down Expand Up @@ -95,6 +95,7 @@
"helmet": "^3.21.2",
"hot-shots": "^8.3.2",
"http-proxy": "^1.18.1",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "5.0.0",
"ioredis": "^4.16.3",
"is-base64": "^1.1.0",
Expand Down Expand Up @@ -157,13 +158,14 @@
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^27.4.0",
"eslint-plugin-jsdoc": "^37.9.3",
"eslint-plugin-jsdoc": "^46.8.2",
"eslint-plugin-no-only-tests": "^2.6.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.0.0",
"husky": "^6.0.0",
"jest": "^27.5.1",
"jest-diff": "^27.5.1",
"jest": "^29.7.0",
"jest-diff": "^29.7",
"jest-environment-jsdom": "^29.7.0",
"jest-when": "^3.5.1",
"keygrip": "^1.0.2",
"nock": "^13.2.4",
Expand All @@ -175,7 +177,7 @@
"smee-client": "^1.2.2",
"sqlite3": "^5.1.5",
"supertest": "^6.2.2",
"ts-jest": "~27.1.3",
"ts-jest": "^29.1.1",
"ts-node": "^10.5.0",
"ts-node-dev": "^2.0.0",
"yaml-lint": "^1.2.4"
Expand All @@ -184,7 +186,7 @@
"@atlassian/sqs-queue-dlq-service": "^2.1.1"
},
"volta": {
"node": "14.21.1",
"node": "18.18.1",
"yarn": "1.22.18"
}
}
2 changes: 1 addition & 1 deletion spa/jest.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"^.+\\.tsx?$": "ts-jest"
},
"setupFilesAfterEnv": [
"@testing-library/jest-dom/extend-expect"
"./setup.ts"
]
}
2 changes: 1 addition & 1 deletion spa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"simplebar-react": "^3.2.4"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.5.2",
Expand Down
1 change: 1 addition & 0 deletions spa/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "@testing-library/jest-dom";
10 changes: 10 additions & 0 deletions spa/src/components/Error/KnownErrors/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Modal, {
import TextArea from "@atlaskit/textarea";
import Spinner from "@atlaskit/spinner";
import Button from "@atlaskit/button";
import WarningIcon from "@atlaskit/icon/glyph/warning";

const olStyle = css`
padding-left: 1.2em;
Expand All @@ -35,6 +36,11 @@ const linkStyle = css`
const textAreaStyle = css`
margin-top: 20px;
`;
const expireTextWrapperStyle = css`
display: flex;
align-items: center;
margin-top: ${token("space.100")};
`;

/************************************************************************
* UI view for the 3 known errors
Expand Down Expand Up @@ -137,6 +143,10 @@ export const ErrorForNonAdmins = ({ orgName, adminOrgsUrl, onPopupBlocked, defer
Find an organization owner
</a>
</div>
<div css={expireTextWrapperStyle}>
<WarningIcon label="warning" primaryColor={token("color.background.warning.bold")} />
<b>Note that the following link will expire after 2 days.</b>
</div>
<TextArea
onCopy={() => {
analyticsClient.sendUIEvent({ actionSubject: "copiedDeferredInstallationUrl", action: "clicked"}, { type: "cloud" });
Expand Down
47 changes: 47 additions & 0 deletions spa/src/pages/DeferredInstallation/DefaultState/forbidden.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/** @jsxImportSource @emotion/react */
import Step from "../../../components/Step";
import { css } from "@emotion/react";
import { token } from "@atlaskit/tokens";
import { popup } from "../../../utils";
import analyticsClient from "../../../analytics";

const paragraphStyle = css`
color: ${token("color.text.subtle")};
margin: ${token("space.0")};
`;
const noAdminDivStyle = css`
margin-top: ${token("space.200")};
`;
const linkStyle = css`
cursor: pointer;
padding-left: 0;
padding-right: 0;
`;

const ForbiddenState = ({ orgName, requestId } : { orgName: string; requestId: string; }) => {
const getOrgOwnerUrl = async () => {
// TODO: Need to get this URL for Enterprise users too, this is only for Cloud users
popup(`https://github.com/orgs/${orgName}/people?query=role%3Aowner`);
analyticsClient.sendUIEvent({ actionSubject: "checkOrgAdmin", action: "clicked"}, { type: "cloud", from: "DeferredInstallationFailedScreen" }, requestId);
};

return (
<Step title="Can’t connect this organization because you don’t have owner permissions">
<div css={noAdminDivStyle}>
<p css={paragraphStyle}>
The GitHub account you’ve used doesn’t have owner permissions
for organization {orgName}.
</p>
<br/>
<p css={paragraphStyle}>
Let the person who sent you the request know to{" "}
<a css={linkStyle} onClick={getOrgOwnerUrl}>
find an owner for that organization.
</a>
</p>
</div>
</Step>
);
};

export default ForbiddenState;
135 changes: 135 additions & 0 deletions spa/src/pages/DeferredInstallation/DefaultState/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/** @jsxImportSource @emotion/react */
import { Box, xcss } from "@atlaskit/primitives";
import InfoIcon from "@atlaskit/icon/glyph/info";
import Button from "@atlaskit/button";
import { css } from "@emotion/react";
import { token } from "@atlaskit/tokens";
import Step from "../../../components/Step";
import { useEffect, useState } from "react";
import { AxiosError } from "axios";
import OAuthManager from "../../../services/oauth-manager";
import DeferralManager from "../../../services/deferral-manager";
import analyticsClient from "../../../analytics";
import { useNavigate } from "react-router-dom";
import { StateCallbacksForDefaultDeferredState } from "rest-interfaces";

const boxStyles = xcss({
borderBlockWidth: token("space.500"),
borderStyle: "solid",
borderColor: "color.border",
borderRadius: "border.radius.050",
borderWidth: "border.width",
marginTop: token("space.200"),
marginBottom: token("space.200"),
display: "flex",
alignItems: "center",
});
const paragraphStyle = css`
color: ${token("color.text.subtle")};
margin: ${token("space.0")};
`;
const infoParaStyle = css`
padding-left: 16px;
`;

const DefaultState = ({
orgName,
jiraHost,
requestId,
callbacks,
}: {
orgName: string;
jiraHost: string;
requestId: string;
callbacks: StateCallbacksForDefaultDeferredState;
}) => {
const navigate = useNavigate();
const { setIsLoading, setForbidden, onPopupBlocked } = callbacks;
const [isLoggedIn, setIsLoggedIn] = useState(false);

// Finish the OAuth dance if authenticated
useEffect(() => {
const handler = async (event: MessageEvent) => {
if (event.data?.type === "oauth-callback" && event.data?.code) {
const response: boolean | AxiosError = await OAuthManager.finishOAuthFlow(event.data?.code, event.data?.state);
setIsLoading(false);
if (response instanceof AxiosError) {
return;
}
setIsLoggedIn(true);
}
};
window.addEventListener("message", handler);
return () => {
window.removeEventListener("message", handler);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

// Start the deferral connection if authenticated
useEffect(() => {
const connectDeferredOrgOrg = async () => {
if (requestId) {
setIsLoading(true);
const status: boolean | AxiosError = await DeferralManager.connectOrgByDeferral(requestId);
if (status instanceof AxiosError) {
setForbidden(true);
analyticsClient.sendScreenEvent({ name: "DeferredInstallationFailedScreen" }, { type: "cloud" }, requestId);
}
else if (status) {
setForbidden(false);
navigate("/spa/connected", { state: { orgLogin: orgName, requestId } });
} else {
setForbidden(true);
}
setIsLoading(false);
}
};

isLoggedIn && connectDeferredOrgOrg();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ isLoggedIn ]);

// Authenticate if no token/username is set
const authenticate = async () => {
setIsLoading(true);
try {
analyticsClient.sendUIEvent({ actionSubject: "signInAndConnectThroughDeferredInstallationStartScreen", action: "clicked"}, { type: "cloud" }, requestId);
await OAuthManager.authenticateInGitHub({
onWinClosed: () => {
setIsLoading(false);
}, onPopupBlocked
});
} catch (e) {
// TODO: print alert error
console.error("check error", e);
} finally {
setIsLoading(false);
}
};

return (
<Step
title={`Connect GitHub organization ${orgName} to Jira Software`}
>
<>
<p css={paragraphStyle}>
A Jira administrator has asked for approval to connect the
GitHub organization {orgName} to the Jira site {jiraHost}.
</p>
<Box padding="space.200" xcss={boxStyles}>
<InfoIcon label="differed-installation-info" size="small"/>
<p css={[paragraphStyle, infoParaStyle]}>
This will make all repositories in {orgName} available to all projects in {jiraHost}. Import work from those
GitHub repositories into Jira.
</p>
</Box>
<Button appearance="primary" onClick={authenticate}>
Sign in & connect
</Button>
</>
</Step>
);
};

export default DefaultState;
15 changes: 15 additions & 0 deletions spa/src/pages/DeferredInstallation/ErrorState/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ErrorObjType } from "../../../utils/modifyError";
import ErrorUI from "../../../components/Error";
import Step from "../../../components/Step";

const ErrorState = ({ error }: { error: ErrorObjType}) => <>
<ErrorUI type={error.type} message={error.message} />
<Step title="Connect a GitHub organization to Jira software">
<div>
Please inform the person who sent you the link that the link <br/>
has expired and send a new link.
</div>
</Step>
</>;

export default ErrorState;
Loading

0 comments on commit bb7d683

Please sign in to comment.