Update Connection provider path (#21678)
## Before After connecting to oAuth linear app connection: <img width="1512" height="851" alt="image" src="https://github.com/user-attachments/assets/39b94aaf-648f-46a6-8f4d-deb1cb7e22c5" /> ## After Redirects to Linear <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21678?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -40,8 +40,8 @@ this — the OAuth credentials are already configured.
|
||||
### 1. Register an OAuth app in Linear
|
||||
|
||||
1. Visit https://linear.app/settings/api/applications/new.
|
||||
2. Set the **Redirect URI** to `<SERVER_URL>/apps/oauth/callback` (for
|
||||
local dev: `http://localhost:3000/apps/oauth/callback`).
|
||||
2. Set the **Redirect URI** to `<SERVER_URL>/auth/apps/callback` (for
|
||||
local dev: `http://localhost:3000/auth/apps/callback`).
|
||||
3. Copy the generated **Client ID** and **Client Secret**.
|
||||
|
||||
### 2. Wire the credentials into Twenty
|
||||
|
||||
@@ -79,7 +79,7 @@ Both routes require an authenticated Twenty user and use the same shared Slack c
|
||||
reinstall the Slack app to the workspace) so the token picks up new scopes.
|
||||
|
||||
3. Set the **Redirect URL** on the Slack app to
|
||||
`<YOUR_TWENTY_SERVER_URL>/apps/oauth/callback` — the same origin your
|
||||
`<YOUR_TWENTY_SERVER_URL>/auth/apps/callback` — the same origin your
|
||||
Twenty **server** uses for API routes (the callback is not served by the SPA
|
||||
alone). Local monorepo dev often uses `http://localhost:3000` (confirm the
|
||||
port your `twenty-server` / `SERVER_URL` actually uses).
|
||||
|
||||
@@ -122,7 +122,7 @@ Use plain product language:
|
||||
- Name the Twenty objects and views users will actually interact with.
|
||||
- Explain setup variables by their exact names.
|
||||
- Distinguish server admin setup from workspace member usage.
|
||||
- For OAuth connections, mention the provider redirect URI: `<SERVER_URL>/apps/oauth/callback`.
|
||||
- For OAuth connections, mention the provider redirect URI: `<SERVER_URL>/auth/apps/callback`.
|
||||
- Document permissions in terms of user risk: read, create, update, soft delete, destroy, third-party send.
|
||||
|
||||
Avoid:
|
||||
|
||||
@@ -82,7 +82,7 @@ Key points:
|
||||
The OAuth callback URL your provider needs to whitelist is:
|
||||
|
||||
```
|
||||
https://<your-twenty-server>/apps/oauth/callback
|
||||
https://<your-twenty-server>/auth/apps/callback
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
@@ -182,7 +182,7 @@ Multiple connections per (user, provider) are allowed, so the same user can hold
|
||||
For each connection provider, the server admin needs to register an OAuth app at the third party first.
|
||||
|
||||
1. Go to the provider's developer settings (e.g. https://linear.app/settings/api/applications/new).
|
||||
2. Set the **Redirect URI** to `<SERVER_URL>/apps/oauth/callback`.
|
||||
2. Set the **Redirect URI** to `<SERVER_URL>/auth/apps/callback`.
|
||||
3. Copy the generated **Client ID** and **Client Secret**.
|
||||
4. Open the installed app in Twenty as a server admin → set the values on the corresponding `serverVariables`.
|
||||
5. Workspace members can then add connections from the per-app **Connections** section.
|
||||
|
||||
@@ -7,7 +7,7 @@ import { GenerateTransientTokenDocument } from '~/generated-metadata/graphql';
|
||||
|
||||
// Mints a transient token then redirects to the generic app OAuth endpoint.
|
||||
// Mirrors `useTriggerApisOAuth` for Google/Microsoft, but the URL template is
|
||||
// /apps/oauth/authorize and works for any app-declared OAuth provider.
|
||||
// /auth/apps/authorize and works for any app-declared OAuth provider.
|
||||
export const useTriggerAppOAuth = () => {
|
||||
const [generateTransientToken] = useMutation(GenerateTransientTokenDocument);
|
||||
const { redirect } = useRedirect();
|
||||
@@ -58,7 +58,7 @@ export const useTriggerAppOAuth = () => {
|
||||
}
|
||||
|
||||
redirect(
|
||||
`${REACT_APP_SERVER_BASE_URL}/apps/oauth/authorize?${params.toString()}`,
|
||||
`${REACT_APP_SERVER_BASE_URL}/auth/apps/authorize?${params.toString()}`,
|
||||
);
|
||||
},
|
||||
[generateTransientToken, redirect],
|
||||
|
||||
+1
-1
@@ -172,7 +172,7 @@ describe('ConnectionProviderOAuthFlowService', () => {
|
||||
expect(url.searchParams.get('scope')).toBe('read write');
|
||||
expect(url.searchParams.get('state')).toBe('signed-state-token');
|
||||
expect(url.searchParams.get('redirect_uri')).toBe(
|
||||
'https://api.example.com/apps/oauth/callback',
|
||||
'https://api.example.com/auth/apps/callback',
|
||||
);
|
||||
expect(url.searchParams.has('code_challenge')).toBe(false);
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent
|
||||
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
||||
import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard';
|
||||
|
||||
@Controller('apps/oauth')
|
||||
@Controller('auth/apps')
|
||||
@UseGuards(PublicEndpointGuard, NoPermissionGuard)
|
||||
export class ConnectionProviderOAuthController {
|
||||
private readonly logger = new Logger(ConnectionProviderOAuthController.name);
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
// signed `state` parameter, so a single redirect URL configured at the
|
||||
// OAuth provider serves every workspace.
|
||||
export const buildAppOAuthCallbackUrl = (serverUrl: string): string =>
|
||||
new URL('/apps/oauth/callback', serverUrl).toString();
|
||||
new URL('/auth/apps/callback', serverUrl).toString();
|
||||
|
||||
Reference in New Issue
Block a user