docs: adds laravel forge app connection docs
@@ -125,6 +125,7 @@
|
||||
"integrations/app-connections/hashicorp-vault",
|
||||
"integrations/app-connections/heroku",
|
||||
"integrations/app-connections/humanitec",
|
||||
"integrations/app-connections/laravel-forge",
|
||||
"integrations/app-connections/ldap",
|
||||
"integrations/app-connections/mssql",
|
||||
"integrations/app-connections/mysql",
|
||||
|
||||
|
After Width: | Height: | Size: 176 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 137 KiB |
|
After Width: | Height: | Size: 333 KiB |
|
After Width: | Height: | Size: 504 KiB |
|
After Width: | Height: | Size: 296 KiB |
|
After Width: | Height: | Size: 200 KiB |
107
docs/integrations/app-connections/laravel-forge.mdx
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
title: "Laravel Forge Connection"
|
||||
description: "Learn how to configure a Laravel Forge Connection for Infisical."
|
||||
---
|
||||
|
||||
Infisical supports the use of [API Tokens](https://forge.laravel.com/docs/api#create-a-new-api-token) to connect with Laravel Forge.
|
||||
|
||||
## Create Laravel Forge API Token
|
||||
|
||||
<Steps>
|
||||
<Step title="From your Laravel Forge dashboard, click on your user avatar and go to 'API'">
|
||||

|
||||
</Step>
|
||||
<Step title="Click 'Create Token'">
|
||||

|
||||
</Step>
|
||||
<Step title="Provide Token Information">
|
||||
Provide a name for your token and select the following permissions:
|
||||
- `user:view`
|
||||
- `organization:view`
|
||||
- `server:view`
|
||||
- `site:manage-environment`
|
||||
|
||||
Then click 'Add token'.
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
<Step title="Copy the token securely">
|
||||
Make sure to copy the token now—you won’t be able to access it again.
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Create a Laravel Forge Connection in Infisical
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Infisical UI">
|
||||
<Steps>
|
||||
<Step title="Navigate to App Connections">
|
||||
In your Infisical dashboard, navigate to the **App Connections** page in the desired project.
|
||||

|
||||
</Step>
|
||||
<Step title="Select Laravel Forge Connection">
|
||||
Click **+ Add Connection** and choose **Laravel Forge** Connection from the list of integrations.
|
||||

|
||||
</Step>
|
||||
<Step title="Fill out the Laravel Forge Connection form">
|
||||
Complete the form by providing:
|
||||
- A descriptive name for the connection
|
||||
- An optional description
|
||||
- The API Token from the previous step
|
||||

|
||||
</Step>
|
||||
<Step title="Connection created">
|
||||
After submitting the form, your **Laravel Forge Connection** will be successfully created and ready to use with your Infisical project.
|
||||

|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="API">
|
||||
To create a Laravel Forge Connection via API, send a request to the [Create Laravel Forge Connection](/api-reference/endpoints/app-connections/laravel-forge/create) endpoint.
|
||||
|
||||
### Sample request
|
||||
|
||||
```bash Request
|
||||
curl --request POST \
|
||||
--url https://app.infisical.com/api/v1/app-connections/laravel-forge \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"name": "my-laravel-forge-connection",
|
||||
"method": "api-token",
|
||||
"projectId": "7ffbb072-2575-495a-b5b0-127f88caef78",
|
||||
"credentials": {
|
||||
"apiToken": "[API TOKEN]"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Sample response
|
||||
|
||||
```bash Response
|
||||
{
|
||||
"appConnection": {
|
||||
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
|
||||
"name": "my-laravel-forge-connection",
|
||||
"description": null,
|
||||
"projectId": "7ffbb072-2575-495a-b5b0-127f88caef78",
|
||||
"version": 1,
|
||||
"orgId": "abcdef12-3456-7890-abcd-ef1234567890",
|
||||
"createdAt": "2025-10-13T10:15:00.000Z",
|
||||
"updatedAt": "2025-10-13T10:15:00.000Z",
|
||||
"isPlatformManagedCredentials": false,
|
||||
"credentialsHash": "d41d8cd98f00b204e9800998ecf8427e",
|
||||
"app": "laravel-forge",
|
||||
"method": "api-token",
|
||||
"credentials": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -17,10 +17,10 @@ export const SecretSyncModalHeader = ({ destination, isConfigured }: Props) => {
|
||||
<img
|
||||
alt={`${destinationDetails.name} logo`}
|
||||
src={`/images/integrations/${destinationDetails.image}`}
|
||||
className="h-12 w-12 rounded-md bg-bunker-500 p-2"
|
||||
className="bg-bunker-500 h-12 w-12 rounded-md p-2"
|
||||
/>
|
||||
<div>
|
||||
<div className="flex items-center text-mineshaft-300">
|
||||
<div className="text-mineshaft-300 flex items-center">
|
||||
{destinationDetails.name} Sync
|
||||
<a
|
||||
target="_blank"
|
||||
@@ -28,8 +28,8 @@ export const SecretSyncModalHeader = ({ destination, isConfigured }: Props) => {
|
||||
className="mb-1 ml-1"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1 mb-[0.03rem] text-[12px]" />
|
||||
<div className="bg-yellow/20 text-yellow inline-block rounded-md px-1.5 text-sm opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mb-[0.03rem] mr-1 text-[12px]" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
@@ -38,7 +38,7 @@ export const SecretSyncModalHeader = ({ destination, isConfigured }: Props) => {
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<p className="text-sm leading-4 text-mineshaft-400">
|
||||
<p className="text-mineshaft-400 text-sm leading-4">
|
||||
{isConfigured
|
||||
? `Edit ${destinationDetails.name} Sync`
|
||||
: `Sync secrets to ${destinationDetails.name}`}
|
||||
|
||||
@@ -57,7 +57,14 @@ import { SupabaseConnectionMethod } from "@app/hooks/api/appConnections/types/su
|
||||
|
||||
export const APP_CONNECTION_MAP: Record<
|
||||
AppConnection,
|
||||
{ name: string; image: string; size?: number; icon?: IconDefinition; enterprise?: boolean }
|
||||
{
|
||||
name: string;
|
||||
image: string;
|
||||
size?: number;
|
||||
icon?: IconDefinition;
|
||||
enterprise?: boolean;
|
||||
imageClassName?: string;
|
||||
}
|
||||
> = {
|
||||
[AppConnection.AWS]: { name: "AWS", image: "Amazon Web Services.png" },
|
||||
[AppConnection.GitHub]: { name: "GitHub", image: "GitHub.png" },
|
||||
@@ -117,7 +124,11 @@ export const APP_CONNECTION_MAP: Record<
|
||||
},
|
||||
[AppConnection.Okta]: { name: "Okta", image: "Okta.png" },
|
||||
[AppConnection.Redis]: { name: "Redis", image: "Redis.png" },
|
||||
[AppConnection.LaravelForge]: { name: "Laravel Forge", image: "Laravel Forge.png" }
|
||||
[AppConnection.LaravelForge]: {
|
||||
name: "Laravel Forge",
|
||||
image: "Laravel Forge.png",
|
||||
imageClassName: "object-contain"
|
||||
}
|
||||
};
|
||||
|
||||
export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) => {
|
||||
|
||||
@@ -14,22 +14,22 @@ export const AppConnectionHeader = ({ app, isConnected, onBack }: Props) => {
|
||||
const appDetails = APP_CONNECTION_MAP[app];
|
||||
|
||||
return (
|
||||
<div className="mb-4 flex w-full items-start gap-2 border-b border-mineshaft-500 pb-4">
|
||||
<div className="border-mineshaft-500 mb-4 flex w-full items-start gap-2 border-b pb-4">
|
||||
<div className="relative">
|
||||
<img
|
||||
alt={`${appDetails.name} logo`}
|
||||
src={`/images/integrations/${appDetails.image}`}
|
||||
className="h-12 w-12 rounded-md bg-bunker-500 p-2"
|
||||
className={`bg-bunker-500 h-12 w-12 rounded-md p-2 ${appDetails.imageClassName}`}
|
||||
/>
|
||||
{appDetails.icon && (
|
||||
<FontAwesomeIcon
|
||||
icon={appDetails.icon}
|
||||
className="absolute right-1 bottom-1 text-primary-700"
|
||||
className="text-primary-700 absolute bottom-1 right-1"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center text-mineshaft-300">
|
||||
<div className="text-mineshaft-300 flex items-center">
|
||||
{appDetails.name}
|
||||
<a
|
||||
href={`https://infisical.com/docs/integrations/app-connections/${app}`}
|
||||
@@ -37,8 +37,8 @@ export const AppConnectionHeader = ({ app, isConnected, onBack }: Props) => {
|
||||
className="mb-1 ml-1"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1 mb-[0.03rem] text-[12px]" />
|
||||
<div className="bg-yellow/20 text-yellow inline-block rounded-md px-1.5 text-sm opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mb-[0.03rem] mr-1 text-[12px]" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
@@ -47,14 +47,14 @@ export const AppConnectionHeader = ({ app, isConnected, onBack }: Props) => {
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<p className="text-sm leading-4 text-mineshaft-400">
|
||||
<p className="text-mineshaft-400 text-sm leading-4">
|
||||
{isConnected ? `${appDetails.name} Connection` : `Connect to ${appDetails.name}`}
|
||||
</p>
|
||||
</div>
|
||||
{onBack && (
|
||||
<button
|
||||
type="button"
|
||||
className="mt-1 ml-auto text-xs text-mineshaft-400 underline underline-offset-2 hover:text-mineshaft-300"
|
||||
className="text-mineshaft-400 hover:text-mineshaft-300 ml-auto mt-1 text-xs underline underline-offset-2"
|
||||
onClick={onBack}
|
||||
>
|
||||
Select another App
|
||||
|
||||
@@ -46,7 +46,7 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
|
||||
return (
|
||||
<div className="flex h-full flex-col items-center justify-center py-2.5">
|
||||
<Spinner size="lg" className="text-mineshaft-500" />
|
||||
<p className="mt-4 text-sm text-mineshaft-400">Loading options...</p>
|
||||
<p className="text-mineshaft-400 mt-4 text-sm">Loading options...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
|
||||
placeholder="Search options..."
|
||||
className="bg-mineshaft-800 placeholder:text-mineshaft-400"
|
||||
/>
|
||||
<div className="grid h-118 grid-cols-4 content-start gap-2">
|
||||
<div className="h-118 grid grid-cols-4 content-start gap-2">
|
||||
{filteredOptions.slice(offset, perPage * page)?.map((option) => {
|
||||
const {
|
||||
image,
|
||||
@@ -78,9 +78,9 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
|
||||
? handlePopUpOpen("upgradePlan")
|
||||
: onSelect(option.app)
|
||||
}
|
||||
className="group relative flex h-28 cursor-pointer flex-col items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-700 p-4 duration-200 hover:bg-mineshaft-600"
|
||||
className="border-mineshaft-600 bg-mineshaft-700 hover:bg-mineshaft-600 group relative flex h-28 cursor-pointer flex-col items-center justify-center rounded-md border p-4 duration-200"
|
||||
>
|
||||
<div className="relative">
|
||||
{image && (
|
||||
<img
|
||||
src={`/images/integrations/${image}`}
|
||||
style={{
|
||||
@@ -89,14 +89,16 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
|
||||
className="mt-auto"
|
||||
alt={`${name} logo`}
|
||||
/>
|
||||
{icon && (
|
||||
)}
|
||||
{icon && (
|
||||
<div className="relative">
|
||||
<FontAwesomeIcon
|
||||
className="absolute -right-1.5 -bottom-1.5 text-primary-700"
|
||||
className="text-primary-700 absolute -bottom-1.5 -right-1.5"
|
||||
size="xl"
|
||||
icon={icon}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-auto max-w-xs text-center text-xs font-medium text-gray-300 duration-200 group-hover:text-gray-200">
|
||||
{name}
|
||||
</div>
|
||||
@@ -125,7 +127,7 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
|
||||
service you're looking for,`}{" "}
|
||||
<a
|
||||
target="_blank"
|
||||
className="underline hover:text-mineshaft-300"
|
||||
className="hover:text-mineshaft-300 underline"
|
||||
href="https://infisical.com/slack"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
@@ -134,7 +136,7 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
|
||||
or{" "}
|
||||
<a
|
||||
target="_blank"
|
||||
className="underline hover:text-mineshaft-300"
|
||||
className="hover:text-mineshaft-300 underline"
|
||||
href="https://github.com/Infisical/infisical/discussions"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
@@ -145,7 +147,7 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
|
||||
</>
|
||||
}
|
||||
>
|
||||
<div className="-ml-3 flex items-center gap-1.5 text-mineshaft-400">
|
||||
<div className="text-mineshaft-400 -ml-3 flex items-center gap-1.5">
|
||||
<span className="text-xs">
|
||||
Don't see the third-party service you're looking for?
|
||||
</span>
|
||||
|
||||