Merging upstream changes.

This commit is contained in:
George Gale
2022-12-19 10:58:57 +01:00
64 changed files with 3205 additions and 124 deletions
+6 -2
View File
@@ -14,8 +14,12 @@ declare global {
JWT_SIGNUP_SECRET: string;
MONGO_URL: string;
NODE_ENV: 'development' | 'staging' | 'testing' | 'production';
OAUTH_CLIENT_SECRET_HEROKU: string;
OAUTH_TOKEN_URL_HEROKU: string;
CLIENT_ID_HEROKU: string;
CLIENT_ID_VERCEL: string;
CLIENT_ID_NETLIFY: string;
CLIENT_SECRET_HEROKU: string;
CLIENT_SECRET_VERCEL: string;
CLIENT_SECRET_NETLIFY: string;
POSTHOG_HOST: string;
POSTHOG_PROJECT_API_KEY: string;
PRIVATE_KEY: string;
+4 -2
View File
@@ -10,7 +10,8 @@ const JWT_SIGNUP_LIFETIME = process.env.JWT_SIGNUP_LIFETIME! || '15m';
const JWT_SIGNUP_SECRET = process.env.JWT_SIGNUP_SECRET!;
const MONGO_URL = process.env.MONGO_URL!;
const NODE_ENV = process.env.NODE_ENV! || 'production';
const OAUTH_CLIENT_SECRET_HEROKU = process.env.OAUTH_CLIENT_SECRET_HEROKU!;
const CLIENT_SECRET_HEROKU = process.env.CLIENT_SECRET_HEROKU!;
const CLIENT_ID_HEROKU = process.env.CLIENT_ID_HEROKU!;
const CLIENT_ID_VERCEL = process.env.CLIENT_ID_VERCEL!;
const CLIENT_ID_NETLIFY = process.env.CLIENT_ID_NETLIFY!;
const CLIENT_ID_GITHUB =
@@ -54,10 +55,11 @@ export {
JWT_SIGNUP_SECRET,
MONGO_URL,
NODE_ENV,
OAUTH_CLIENT_SECRET_HEROKU,
CLIENT_ID_HEROKU,
CLIENT_ID_VERCEL,
CLIENT_ID_NETLIFY,
CLIENT_ID_GITHUB,
CLIENT_SECRET_HEROKU,
CLIENT_SECRET_VERCEL,
CLIENT_SECRET_NETLIFY,
CLIENT_SECRET_GITHUB,
@@ -3,10 +3,19 @@ import * as Sentry from '@sentry/node';
import axios from 'axios';
import { readFileSync } from 'fs';
import { IntegrationAuth, Integration } from '../models';
import { INTEGRATION_SET, ENV_DEV } from '../variables';
import { INTEGRATION_SET, INTEGRATION_OPTIONS, ENV_DEV } from '../variables';
import { IntegrationService } from '../services';
import { getApps, revokeAccess } from '../integrations';
export const getIntegrationOptions = async (
req: Request,
res: Response
) => {
return res.status(200).send({
integrationOptions: INTEGRATION_OPTIONS
});
}
/**
* Perform OAuth2 code-token exchange as part of integration [integration] for workspace with id [workspaceId]
* @param req
+36 -1
View File
@@ -11,9 +11,9 @@ import {
INTEGRATION_GITHUB_TOKEN_URL,
ACTION_PUSH_TO_HEROKU
} from '../variables';
import {
SITE_URL,
OAUTH_CLIENT_SECRET_HEROKU,
CLIENT_ID_VERCEL,
CLIENT_ID_NETLIFY,
CLIENT_ID_GITHUB,
@@ -117,6 +117,7 @@ const exchangeCode = async ({
* @returns {String} obj2.refreshToken - refresh token for Heroku API
* @returns {Date} obj2.accessExpiresAt - date of expiration for access token
*/
<<<<<<< HEAD
const exchangeCodeHeroku = async ({ code }: { code: string }) => {
let res: ExchangeCodeHerokuResponse;
const accessExpiresAt = new Date();
@@ -145,6 +146,40 @@ const exchangeCodeHeroku = async ({ code }: { code: string }) => {
accessExpiresAt
};
};
=======
const exchangeCodeHeroku = async ({
code
}: {
code: string;
}) => {
let res: ExchangeCodeHerokuResponse;
let accessExpiresAt = new Date();
try {
res = (await axios.post(
INTEGRATION_HEROKU_TOKEN_URL,
new URLSearchParams({
grant_type: 'authorization_code',
code: code,
client_secret: CLIENT_SECRET_HEROKU
} as any)
)).data;
accessExpiresAt.setSeconds(
accessExpiresAt.getSeconds() + res.expires_in
);
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed OAuth2 code-token exchange with Heroku');
}
return ({
accessToken: res.access_token,
refreshToken: res.refresh_token,
accessExpiresAt
});
}
>>>>>>> 5444382d5ae1fabf1107434a856b58b9f09c67f6
/**
* Return [accessToken], [accessExpiresAt], and [refreshToken] for Vercel
+19 -2
View File
@@ -1,8 +1,12 @@
import axios from 'axios';
import * as Sentry from '@sentry/node';
import { INTEGRATION_HEROKU } from '../variables';
import { OAUTH_CLIENT_SECRET_HEROKU } from '../config';
import { INTEGRATION_HEROKU_TOKEN_URL } from '../variables';
import {
CLIENT_SECRET_HEROKU
} from '../config';
import {
INTEGRATION_HEROKU_TOKEN_URL
} from '../variables';
/**
* Return new access token by exchanging refresh token [refreshToken] for integration
@@ -48,6 +52,7 @@ const exchangeRefreshHeroku = async ({
}: {
refreshToken: string;
}) => {
<<<<<<< HEAD
let accessToken;
try {
const res = await axios.post(
@@ -58,6 +63,18 @@ const exchangeRefreshHeroku = async ({
client_secret: OAUTH_CLIENT_SECRET_HEROKU
} as any)
);
=======
let accessToken;
try {
const res = await axios.post(
INTEGRATION_HEROKU_TOKEN_URL,
new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_secret: CLIENT_SECRET_HEROKU
} as any)
);
>>>>>>> 5444382d5ae1fabf1107434a856b58b9f09c67f6
accessToken = res.data.access_token;
} catch (err) {
@@ -10,14 +10,16 @@ import { validateMembership } from '../helpers/membership';
* @param {Object} obj
* @param {String[]} obj.acceptedRoles - accepted workspace roles
* @param {String[]} obj.acceptedStatuses - accepted workspace statuses
* @param {Boolean} obj.attachRefresh - whether or not to decrypt and attach integration authorization refresh token onto request
* @param {Boolean} obj.attachAccessToken - whether or not to decrypt and attach integration authorization access token onto request
*/
const requireIntegrationAuthorizationAuth = ({
acceptedRoles,
acceptedStatuses
acceptedStatuses,
attachAccessToken = true
}: {
acceptedRoles: string[];
acceptedStatuses: string[];
attachAccessToken?: boolean;
}) => {
return async (req: Request, res: Response, next: NextFunction) => {
try {
@@ -41,9 +43,11 @@ const requireIntegrationAuthorizationAuth = ({
});
req.integrationAuth = integrationAuth;
req.accessToken = await IntegrationService.getIntegrationAuthAccess({
integrationAuthId: integrationAuth._id.toString()
});
if (attachAccessToken) {
req.accessToken = await IntegrationService.getIntegrationAuthAccess({
integrationAuthId: integrationAuth._id.toString()
});
}
return next();
} catch (err) {
+8 -1
View File
@@ -10,6 +10,12 @@ import {
import { ADMIN, MEMBER, GRANTED } from '../variables';
import { integrationAuthController } from '../controllers';
router.get(
'/integration-options',
requireAuth,
integrationAuthController.getIntegrationOptions
);
router.post(
'/oauth-token',
requireAuth,
@@ -42,7 +48,8 @@ router.delete(
requireAuth,
requireIntegrationAuthorizationAuth({
acceptedRoles: [ADMIN, MEMBER],
acceptedStatuses: [GRANTED]
acceptedStatuses: [GRANTED],
attachAccessToken: false
}),
param('integrationAuthId'),
validateRequest,
+4 -2
View File
@@ -19,7 +19,8 @@ import {
INTEGRATION_HEROKU_API_URL,
INTEGRATION_VERCEL_API_URL,
INTEGRATION_NETLIFY_API_URL,
INTEGRATION_GITHUB_API_URL
INTEGRATION_GITHUB_API_URL,
INTEGRATION_OPTIONS
} from './integration';
import {
OWNER,
@@ -68,5 +69,6 @@ export {
INTEGRATION_GITHUB_API_URL,
EVENT_PUSH_SECRETS,
EVENT_PULL_SECRETS,
ACTION_PUSH_TO_HEROKU
ACTION_PUSH_TO_HEROKU,
INTEGRATION_OPTIONS
};
+82 -1
View File
@@ -1,3 +1,8 @@
import {
CLIENT_ID_HEROKU,
CLIENT_ID_NETLIFY
} from '../config';
// integrations
const INTEGRATION_HEROKU = 'heroku';
const INTEGRATION_VERCEL = 'vercel';
@@ -27,6 +32,81 @@ const INTEGRATION_VERCEL_API_URL = 'https://api.vercel.com';
const INTEGRATION_NETLIFY_API_URL = 'https://api.netlify.com';
const INTEGRATION_GITHUB_API_URL = ' https://api.github.com/';
const INTEGRATION_OPTIONS = [
{
name: 'Heroku',
slug: 'heroku',
image: 'Heroku',
isAvailable: true,
type: 'oauth2',
clientId: CLIENT_ID_HEROKU,
docsLink: ''
},
{
name: 'Vercel',
slug: 'vercel',
image: 'Vercel',
isAvailable: true,
type: 'vercel',
clientId: '',
docsLink: ''
},
{
name: 'Netlify',
slug: 'netlify',
image: 'Netlify',
isAvailable: true,
type: 'oauth2',
clientId: CLIENT_ID_NETLIFY,
docsLink: ''
},
{
name: 'Google Cloud Platform',
slug: 'gcp',
image: 'Google Cloud Platform',
isAvailable: false,
type: '',
clientId: '',
docsLink: ''
},
{
name: 'Amazon Web Services',
slug: 'aws',
image: 'Amazon Web Services',
isAvailable: false,
type: '',
clientId: '',
docsLink: ''
},
{
name: 'Microsoft Azure',
slug: 'azure',
image: 'Microsoft Azure',
isAvailable: false,
type: '',
clientId: '',
docsLink: ''
},
{
name: 'Travis CI',
slug: 'travisci',
image: 'Travis CI',
isAvailable: false,
type: '',
clientId: '',
docsLink: ''
},
{
name: 'Circle CI',
slug: 'circleci',
image: 'Circle CI',
isAvailable: false,
type: '',
clientId: '',
docsLink: ''
}
]
export {
INTEGRATION_HEROKU,
INTEGRATION_VERCEL,
@@ -41,5 +121,6 @@ export {
INTEGRATION_HEROKU_API_URL,
INTEGRATION_VERCEL_API_URL,
INTEGRATION_NETLIFY_API_URL,
INTEGRATION_GITHUB_API_URL
INTEGRATION_GITHUB_API_URL,
INTEGRATION_OPTIONS
};