mirror of
https://github.com/docmost/docmost.git
synced 2026-08-22 20:32:13 +10:00
feat(integrations): defer workspace-scoped install until OAuth succeeds
This commit is contained in:
@@ -14,7 +14,11 @@ import {
|
||||
useUpdateIntegrationSettings,
|
||||
} from "../queries/integration-query";
|
||||
import { Integration } from "../types/integration.types";
|
||||
import { getOAuthAuthorizeUrl } from "../services/integration-service";
|
||||
import {
|
||||
getOAuthAuthorizeUrl,
|
||||
getOAuthInstallUrl,
|
||||
} from "../services/integration-service";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
|
||||
export default function Integrations() {
|
||||
const { t } = useTranslation();
|
||||
@@ -31,19 +35,29 @@ export default function Integrations() {
|
||||
const handleInstall = useCallback(
|
||||
async (type: string) => {
|
||||
const definition = available?.find((d) => d.type === type);
|
||||
try {
|
||||
const integration = await installMutation.mutateAsync({ type });
|
||||
if (definition?.oauth?.connectionScope === 'workspace') {
|
||||
const { authorizationUrl } = await getOAuthAuthorizeUrl({
|
||||
integrationId: integration.id,
|
||||
});
|
||||
|
||||
// Workspace-scoped (Slack): the install row is only persisted when the
|
||||
// OAuth callback succeeds. Skip the upfront install API call entirely.
|
||||
if (definition?.oauth?.connectionScope === "workspace") {
|
||||
try {
|
||||
const { authorizationUrl } = await getOAuthInstallUrl({ type });
|
||||
window.location.href = authorizationUrl;
|
||||
} catch (err: any) {
|
||||
notifications.show({
|
||||
message:
|
||||
err?.response?.data?.message ?? t("Failed to start installation"),
|
||||
color: "red",
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
// installMutation's onError already shows a notification
|
||||
return;
|
||||
}
|
||||
|
||||
// Per-user OAuth providers (Linear, Jira, GitHub, ...): keep existing
|
||||
// two-step flow — create the integration row, then individual users
|
||||
// OAuth-connect from /settings/account/connections.
|
||||
installMutation.mutate({ type });
|
||||
},
|
||||
[installMutation, available],
|
||||
[installMutation, available, t],
|
||||
);
|
||||
|
||||
const handleUninstall = useCallback(
|
||||
|
||||
@@ -68,6 +68,21 @@ export async function getOAuthAuthorizeUrl(data: {
|
||||
return req.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* For workspace-scoped providers: returns the authorize URL WITHOUT creating
|
||||
* the integration row. The row is created atomically when the OAuth callback
|
||||
* succeeds; a cancelled OAuth leaves no half-installed state.
|
||||
*/
|
||||
export async function getOAuthInstallUrl(data: {
|
||||
type: string;
|
||||
}): Promise<{ authorizationUrl: string }> {
|
||||
const req = await api.post<{ authorizationUrl: string }>(
|
||||
"/integrations/oauth/install",
|
||||
data,
|
||||
);
|
||||
return req.data;
|
||||
}
|
||||
|
||||
export async function disconnectIntegration(data: {
|
||||
integrationId: string;
|
||||
}): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user