mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 08:27:36 +00:00
Refactor integrations logic and replace hardcoded client ids with envars
This commit is contained in:
+6
-1
@@ -47,7 +47,12 @@ SMTP_PASSWORD=
|
|||||||
|
|
||||||
# Integration
|
# Integration
|
||||||
# Optional only if integration is used
|
# Optional only if integration is used
|
||||||
OAUTH_CLIENT_SECRET_HEROKU=
|
CLIENT_ID_HEROKU=
|
||||||
|
CLIENT_ID_VERCEL=
|
||||||
|
CLIENT_ID_NETLIFY=
|
||||||
|
CLIENT_SECRET_HEROKU=
|
||||||
|
CLIENT_SECRET_VERCEL=
|
||||||
|
CLIENT_SECRET_NETLIFY=
|
||||||
|
|
||||||
# Sentry (optional) for monitoring errors
|
# Sentry (optional) for monitoring errors
|
||||||
SENTRY_DSN=
|
SENTRY_DSN=
|
||||||
|
|||||||
Vendored
+6
-2
@@ -14,8 +14,12 @@ declare global {
|
|||||||
JWT_SIGNUP_SECRET: string;
|
JWT_SIGNUP_SECRET: string;
|
||||||
MONGO_URL: string;
|
MONGO_URL: string;
|
||||||
NODE_ENV: 'development' | 'staging' | 'testing' | 'production';
|
NODE_ENV: 'development' | 'staging' | 'testing' | 'production';
|
||||||
OAUTH_CLIENT_SECRET_HEROKU: string;
|
CLIENT_ID_HEROKU: string;
|
||||||
OAUTH_TOKEN_URL_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_HOST: string;
|
||||||
POSTHOG_PROJECT_API_KEY: string;
|
POSTHOG_PROJECT_API_KEY: string;
|
||||||
PRIVATE_KEY: string;
|
PRIVATE_KEY: string;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const JWT_SIGNUP_LIFETIME = process.env.JWT_SIGNUP_LIFETIME! || '15m';
|
|||||||
const JWT_SIGNUP_SECRET = process.env.JWT_SIGNUP_SECRET!;
|
const JWT_SIGNUP_SECRET = process.env.JWT_SIGNUP_SECRET!;
|
||||||
const MONGO_URL = process.env.MONGO_URL!;
|
const MONGO_URL = process.env.MONGO_URL!;
|
||||||
const NODE_ENV = process.env.NODE_ENV! || 'production';
|
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_VERCEL = process.env.CLIENT_ID_VERCEL!;
|
const CLIENT_ID_VERCEL = process.env.CLIENT_ID_VERCEL!;
|
||||||
const CLIENT_ID_NETLIFY = process.env.CLIENT_ID_NETLIFY!;
|
const CLIENT_ID_NETLIFY = process.env.CLIENT_ID_NETLIFY!;
|
||||||
const CLIENT_SECRET_VERCEL = process.env.CLIENT_SECRET_VERCEL!;
|
const CLIENT_SECRET_VERCEL = process.env.CLIENT_SECRET_VERCEL!;
|
||||||
@@ -49,9 +49,9 @@ export {
|
|||||||
JWT_SIGNUP_SECRET,
|
JWT_SIGNUP_SECRET,
|
||||||
MONGO_URL,
|
MONGO_URL,
|
||||||
NODE_ENV,
|
NODE_ENV,
|
||||||
OAUTH_CLIENT_SECRET_HEROKU,
|
|
||||||
CLIENT_ID_VERCEL,
|
CLIENT_ID_VERCEL,
|
||||||
CLIENT_ID_NETLIFY,
|
CLIENT_ID_NETLIFY,
|
||||||
|
CLIENT_SECRET_HEROKU,
|
||||||
CLIENT_SECRET_VERCEL,
|
CLIENT_SECRET_VERCEL,
|
||||||
CLIENT_SECRET_NETLIFY,
|
CLIENT_SECRET_NETLIFY,
|
||||||
POSTHOG_HOST,
|
POSTHOG_HOST,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
} from '../variables';
|
} from '../variables';
|
||||||
import {
|
import {
|
||||||
SITE_URL,
|
SITE_URL,
|
||||||
OAUTH_CLIENT_SECRET_HEROKU,
|
CLIENT_SECRET_HEROKU,
|
||||||
CLIENT_ID_VERCEL,
|
CLIENT_ID_VERCEL,
|
||||||
CLIENT_ID_NETLIFY,
|
CLIENT_ID_NETLIFY,
|
||||||
CLIENT_SECRET_VERCEL,
|
CLIENT_SECRET_VERCEL,
|
||||||
@@ -114,7 +114,7 @@ const exchangeCodeHeroku = async ({
|
|||||||
new URLSearchParams({
|
new URLSearchParams({
|
||||||
grant_type: 'authorization_code',
|
grant_type: 'authorization_code',
|
||||||
code: code,
|
code: code,
|
||||||
client_secret: OAUTH_CLIENT_SECRET_HEROKU
|
client_secret: CLIENT_SECRET_HEROKU
|
||||||
} as any)
|
} as any)
|
||||||
)).data;
|
)).data;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import axios from 'axios';
|
|||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
import { INTEGRATION_HEROKU } from '../variables';
|
import { INTEGRATION_HEROKU } from '../variables';
|
||||||
import {
|
import {
|
||||||
OAUTH_CLIENT_SECRET_HEROKU
|
CLIENT_SECRET_HEROKU
|
||||||
} from '../config';
|
} from '../config';
|
||||||
import {
|
import {
|
||||||
INTEGRATION_HEROKU_TOKEN_URL
|
INTEGRATION_HEROKU_TOKEN_URL
|
||||||
@@ -59,7 +59,7 @@ const exchangeRefreshHeroku = async ({
|
|||||||
new URLSearchParams({
|
new URLSearchParams({
|
||||||
grant_type: 'refresh_token',
|
grant_type: 'refresh_token',
|
||||||
refresh_token: refreshToken,
|
refresh_token: refreshToken,
|
||||||
client_secret: OAUTH_CLIENT_SECRET_HEROKU
|
client_secret: CLIENT_SECRET_HEROKU
|
||||||
} as any)
|
} as any)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,16 @@ import { validateMembership } from '../helpers/membership';
|
|||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
||||||
* @param {String[]} obj.acceptedStatuses - accepted workspace statuses
|
* @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 = ({
|
const requireIntegrationAuthorizationAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses
|
acceptedStatuses,
|
||||||
|
attachAccessToken = true
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
acceptedStatuses: string[];
|
||||||
|
attachAccessToken?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
@@ -41,9 +43,11 @@ const requireIntegrationAuthorizationAuth = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
req.integrationAuth = integrationAuth;
|
req.integrationAuth = integrationAuth;
|
||||||
req.accessToken = await IntegrationService.getIntegrationAuthAccess({
|
if (attachAccessToken) {
|
||||||
integrationAuthId: integrationAuth._id.toString()
|
req.accessToken = await IntegrationService.getIntegrationAuthAccess({
|
||||||
});
|
integrationAuthId: integrationAuth._id.toString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ router.delete(
|
|||||||
requireAuth,
|
requireAuth,
|
||||||
requireIntegrationAuthorizationAuth({
|
requireIntegrationAuthorizationAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [GRANTED]
|
acceptedStatuses: [GRANTED],
|
||||||
|
attachAccessToken: false
|
||||||
}),
|
}),
|
||||||
param('integrationAuthId'),
|
param('integrationAuthId'),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
|
|||||||
@@ -51,8 +51,12 @@ services:
|
|||||||
env_file: .env
|
env_file: .env
|
||||||
environment:
|
environment:
|
||||||
- NEXT_PUBLIC_ENV=development
|
- NEXT_PUBLIC_ENV=development
|
||||||
|
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
|
||||||
|
- NEXT_PUBLIC_SITE_URL=${SITE_URL}
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
|
- NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
|
- NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
|
||||||
|
- NEXT_PUBLIC_CLIENT_ID_HEROKU=${CLIENT_ID_HEROKU}
|
||||||
|
- NEXT_PUBLIC_CLIENT_ID_NETLIFY=${CLIENT_ID_NETLIFY}
|
||||||
networks:
|
networks:
|
||||||
- infisical-dev
|
- infisical-dev
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ services:
|
|||||||
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
|
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
|
- NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
|
- NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
|
||||||
|
- NEXT_PUBLIC_SITE_URL=${SITE_URL}
|
||||||
|
- NEXT_PUBLIC_CLIENT_ID_HEROKU=${CLIENT_ID_HEROKU}
|
||||||
|
- NEXT_PUBLIC_CLIENT_ID_NETLIFY=${CLIENT_ID_NETLIFY}
|
||||||
networks:
|
networks:
|
||||||
- infisical
|
- infisical
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ Configuring Infisical requires setting some environment variables. There is a fi
|
|||||||
| `SMTP_USERNAME` | ❗️ Credential to connect to host (e.g. `[email protected]`) | `None` |
|
| `SMTP_USERNAME` | ❗️ Credential to connect to host (e.g. `[email protected]`) | `None` |
|
||||||
| `SMTP_PASSWORD` | ❗️ Credential to connect to host | `None` |
|
| `SMTP_PASSWORD` | ❗️ Credential to connect to host | `None` |
|
||||||
| `TELEMETRY_ENABLED` | `true` or `false`. [More](../overview). | `true` |
|
| `TELEMETRY_ENABLED` | `true` or `false`. [More](../overview). | `true` |
|
||||||
| `OAUTH_CLIENT_SECRET_HEROKU` | OAuth client secret for Heroku integration | `None` |
|
| `CLIENT_ID_VERCEL` | OAuth client id for Vercel integration | `None` |
|
||||||
| `OAUTH_TOKEN_URL_HEROKU` | OAuth token URL for Heroku integration | `None` |
|
| `CLIENT_ID_NETLIFY` | OAuth client id for Netlify integration | `None` |
|
||||||
|
| `CLIENT_SECRET_HEROKU` | OAuth client secret for Heroku integration | `None` |
|
||||||
|
| `CLIENT_SECRET_VERCEL` | OAuth client secret for Vercel integration | `None` |
|
||||||
|
| `CLIENT_SECRET_NETLIFY` | OAuth client secret for Netlify integration | `None` |
|
||||||
| `SENTRY_DSN` | DSN for error-monitoring with Sentry | `None` |
|
| `SENTRY_DSN` | DSN for error-monitoring with Sentry | `None` |
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ const CloudIntegration = ({
|
|||||||
)
|
)
|
||||||
.map((authorization) => authorization._id)[0],
|
.map((authorization) => authorization._id)[0],
|
||||||
});
|
});
|
||||||
|
|
||||||
router.reload();
|
router.reload();
|
||||||
}}
|
}}
|
||||||
className="cursor-pointer w-max bg-red py-0.5 px-2 rounded-b-md text-xs flex flex-row items-center opacity-0 group-hover:opacity-100 duration-200"
|
className="cursor-pointer w-max bg-red py-0.5 px-2 rounded-b-md text-xs flex flex-row items-center opacity-0 group-hover:opacity-100 duration-200"
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ import getIntegrationApps from "../../pages/api/integrations/GetIntegrationApps"
|
|||||||
import Button from "~/components/basic/buttons/Button";
|
import Button from "~/components/basic/buttons/Button";
|
||||||
import ListBox from "~/components/basic/Listbox";
|
import ListBox from "~/components/basic/Listbox";
|
||||||
|
|
||||||
// TODO: optimize laggy dropdown for app options
|
|
||||||
|
|
||||||
interface Integration {
|
interface Integration {
|
||||||
app?: string;
|
app?: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ const POSTHOG_HOST =
|
|||||||
process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com";
|
process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com";
|
||||||
const STRIPE_PRODUCT_PRO = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_PRO!;
|
const STRIPE_PRODUCT_PRO = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_PRO!;
|
||||||
const STRIPE_PRODUCT_STARTER = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_STARTER!;
|
const STRIPE_PRODUCT_STARTER = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_STARTER!;
|
||||||
|
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL!;
|
||||||
|
const CLIENT_ID_HEROKU = process.env.NEXT_PUBLIC_CLIENT_ID_HEROKU!;
|
||||||
|
const CLIENT_ID_NETLIFY = process.env.NEXT_PUBLIC_CLIENT_ID_NETLIFY!;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ENV,
|
ENV,
|
||||||
@@ -11,4 +14,7 @@ export {
|
|||||||
POSTHOG_HOST,
|
POSTHOG_HOST,
|
||||||
STRIPE_PRODUCT_PRO,
|
STRIPE_PRODUCT_PRO,
|
||||||
STRIPE_PRODUCT_STARTER,
|
STRIPE_PRODUCT_STARTER,
|
||||||
};
|
SITE_URL,
|
||||||
|
CLIENT_ID_HEROKU,
|
||||||
|
CLIENT_ID_NETLIFY
|
||||||
|
};
|
||||||
@@ -8,7 +8,8 @@ import FrameworkIntegrationSection from "~/components/integrations/FrameworkInte
|
|||||||
import CloudIntegrationSection from "~/components/integrations/CloudIntegrationSection";
|
import CloudIntegrationSection from "~/components/integrations/CloudIntegrationSection";
|
||||||
import IntegrationSection from "~/components/integrations/IntegrationSection";
|
import IntegrationSection from "~/components/integrations/IntegrationSection";
|
||||||
import frameworkIntegrationOptions from "../../public/json/frameworkIntegrations.json";
|
import frameworkIntegrationOptions from "../../public/json/frameworkIntegrations.json";
|
||||||
import cloudIntegrationOptions from "../../public/json/cloudIntegrations.json";
|
// import cloudIntegrationOptions from "../../public/json/cloudIntegrations.json";
|
||||||
|
import { cloudIntegrationOptions } from "../../public/data/cloudIntegrations";
|
||||||
import getWorkspaceAuthorizations from "../api/integrations/getWorkspaceAuthorizations";
|
import getWorkspaceAuthorizations from "../api/integrations/getWorkspaceAuthorizations";
|
||||||
import getWorkspaceIntegrations from "../api/integrations/getWorkspaceIntegrations";
|
import getWorkspaceIntegrations from "../api/integrations/getWorkspaceIntegrations";
|
||||||
import getBot from "../api/bot/getBot";
|
import getBot from "../api/bot/getBot";
|
||||||
@@ -29,7 +30,7 @@ export default function Integrations() {
|
|||||||
const [integrations, setIntegrations] = useState([]);
|
const [integrations, setIntegrations] = useState([]);
|
||||||
const [bot, setBot] = useState(null);
|
const [bot, setBot] = useState(null);
|
||||||
const [isActivateBotDialogOpen, setIsActivateBotDialogOpen] = useState(false);
|
const [isActivateBotDialogOpen, setIsActivateBotDialogOpen] = useState(false);
|
||||||
const [isIntegrationAccessTokenDialogOpen, setIntegrationAccessTokenDialogOpen] = useState(true);
|
// const [isIntegrationAccessTokenDialogOpen, setIntegrationAccessTokenDialogOpen] = useState(true);
|
||||||
const [selectedIntegrationOption, setSelectedIntegrationOption] = useState(null);
|
const [selectedIntegrationOption, setSelectedIntegrationOption] = useState(null);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -122,22 +123,20 @@ export default function Integrations() {
|
|||||||
const state = crypto.randomBytes(16).toString("hex");
|
const state = crypto.randomBytes(16).toString("hex");
|
||||||
localStorage.setItem('latestCSRFToken', state);
|
localStorage.setItem('latestCSRFToken', state);
|
||||||
|
|
||||||
// TODO: Add CircleCI, Render, Fly.io
|
|
||||||
|
|
||||||
switch (integrationOption.name) {
|
switch (integrationOption.name) {
|
||||||
case 'Heroku':
|
case 'Heroku':
|
||||||
window.location = `https://id.heroku.com/oauth/authorize?client_id=${integrationOption.clientId}&response_type=code&scope=write-protected&state=${state}`;
|
window.location = `https://id.heroku.com/oauth/authorize?client_id=${integrationOption.clientId}&response_type=code&scope=write-protected&state=${state}`;
|
||||||
break;
|
break;
|
||||||
case 'Vercel':
|
case 'Vercel':
|
||||||
window.location = `https://vercel.com/integrations/infisical/new?state=${state}`;
|
window.location = `https://vercel.com/integrations/infisical-dev/new?state=${state}`;
|
||||||
break;
|
break;
|
||||||
case 'Netlify':
|
case 'Netlify':
|
||||||
window.location = `https://app.netlify.com/authorize?client_id=${integrationOption.clientId}&response_type=code&redirect_uri=${integrationOption.redirectURL}&state=${state}`;
|
window.location = `https://app.netlify.com/authorize?client_id=${integrationOption.clientId}&response_type=code&state=${state}&redirect_uri=${integrationOption.redirectURL}`;
|
||||||
break;
|
|
||||||
case 'Fly.io':
|
|
||||||
console.log('fly.io');
|
|
||||||
setIntegrationAccessTokenDialogOpen(true);
|
|
||||||
break;
|
break;
|
||||||
|
// case 'Fly.io':
|
||||||
|
// console.log('fly.io');
|
||||||
|
// setIntegrationAccessTokenDialogOpen(true);
|
||||||
|
// break;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -163,7 +162,7 @@ export default function Integrations() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// case: bot is not active -> open modal to activate bot
|
// case: bot is not active -> open modal to activate bot
|
||||||
setIsActivateBotOpen(true);
|
setIsActivateBotDialogOpen(true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
@@ -193,13 +192,13 @@ export default function Integrations() {
|
|||||||
handleBotActivate={handleBotActivate}
|
handleBotActivate={handleBotActivate}
|
||||||
handleIntegrationOption={handleIntegrationOption}
|
handleIntegrationOption={handleIntegrationOption}
|
||||||
/>
|
/>
|
||||||
<IntegrationAccessTokenDialog
|
{/* <IntegrationAccessTokenDialog
|
||||||
isOpen={isIntegrationAccessTokenDialogOpen}
|
isOpen={isIntegrationAccessTokenDialogOpen}
|
||||||
closeModal={() => setIntegrationAccessTokenDialogOpen(false)}
|
closeModal={() => setIntegrationAccessTokenDialogOpen(false)}
|
||||||
selectedIntegrationOption={selectedIntegrationOption}
|
selectedIntegrationOption={selectedIntegrationOption}
|
||||||
handleBotActivate={handleBotActivate}
|
handleBotActivate={handleBotActivate}
|
||||||
handleIntegrationOption={handleIntegrationOption}
|
handleIntegrationOption={handleIntegrationOption}
|
||||||
/>
|
/> */}
|
||||||
<IntegrationSection integrations={integrations} />
|
<IntegrationSection integrations={integrations} />
|
||||||
<CloudIntegrationSection
|
<CloudIntegrationSection
|
||||||
cloudIntegrationOptions={cloudIntegrationOptions}
|
cloudIntegrationOptions={cloudIntegrationOptions}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import {
|
||||||
|
SITE_URL,
|
||||||
|
CLIENT_ID_HEROKU,
|
||||||
|
CLIENT_ID_NETLIFY
|
||||||
|
} from '../../components/utilities/config';
|
||||||
|
|
||||||
|
const cloudIntegrationOptions = [
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
redirectURL: `${SITE_URL}/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 { cloudIntegrationOptions };
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
@@ -27,15 +27,6 @@
|
|||||||
"redirectURL": "http://localhost:8080/netlify",
|
"redirectURL": "http://localhost:8080/netlify",
|
||||||
"docsLink": ""
|
"docsLink": ""
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Fly.io",
|
|
||||||
"slug": "flyio",
|
|
||||||
"image": "Google Cloud Platform",
|
|
||||||
"isAvailable": true,
|
|
||||||
"type": "accessToken",
|
|
||||||
"clientId": "",
|
|
||||||
"docsLink": ""
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Google Cloud Platform",
|
"name": "Google Cloud Platform",
|
||||||
"slug": "gcp",
|
"slug": "gcp",
|
||||||
|
|||||||
Reference in New Issue
Block a user