Skip to content

Commit 5d8ed55

Browse files
authored
users connectors module for UOU connectors feature (#130)
1 parent bd816ff commit 5d8ed55

5 files changed

Lines changed: 143 additions & 4 deletions

File tree

src/client.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { createEntitiesModule } from "./modules/entities.js";
33
import { createIntegrationsModule } from "./modules/integrations.js";
44
import { createAuthModule } from "./modules/auth.js";
55
import { createSsoModule } from "./modules/sso.js";
6-
import { createConnectorsModule } from "./modules/connectors.js";
6+
import {
7+
createConnectorsModule,
8+
createUserConnectorsModule,
9+
} from "./modules/connectors.js";
710
import { getAccessToken } from "./utils/auth-utils.js";
811
import { createFunctionsModule } from "./modules/functions.js";
912
import { createAgentsModule } from "./modules/agents.js";
@@ -150,6 +153,7 @@ export function createClient(config: CreateClientConfig): Base44Client {
150153
getSocket,
151154
}),
152155
integrations: createIntegrationsModule(axiosClient, appId),
156+
connectors: createUserConnectorsModule(axiosClient, appId),
153157
auth: userAuthModule,
154158
functions: createFunctionsModule(functionsAxiosClient, appId),
155159
agents: createAgentsModule({

src/client.types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import type { EntitiesModule } from "./modules/entities.types.js";
22
import type { IntegrationsModule } from "./modules/integrations.types.js";
33
import type { AuthModule } from "./modules/auth.types.js";
44
import type { SsoModule } from "./modules/sso.types.js";
5-
import type { ConnectorsModule } from "./modules/connectors.types.js";
5+
import type {
6+
ConnectorsModule,
7+
UserConnectorsModule,
8+
} from "./modules/connectors.types.js";
69
import type { FunctionsModule } from "./modules/functions.types.js";
710
import type { AgentsModule } from "./modules/agents.types.js";
811
import type { AppLogsModule } from "./modules/app-logs.types.js";
@@ -90,6 +93,8 @@ export interface Base44Client {
9093
appLogs: AppLogsModule;
9194
/** {@link AuthModule | Auth module} for user authentication and management. */
9295
auth: AuthModule;
96+
/** {@link UserConnectorsModule | Connectors module} for app-user OAuth flows. */
97+
connectors: UserConnectorsModule;
9398
/** {@link EntitiesModule | Entities module} for CRUD operations on your data models. */
9499
entities: EntitiesModule;
95100
/** {@link FunctionsModule | Functions module} for invoking custom backend functions. */

src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ export type { AppLogsModule } from "./modules/app-logs.types.js";
101101

102102
export type { SsoModule, SsoAccessTokenResponse } from "./modules/sso.types.js";
103103

104-
export type { ConnectorsModule } from "./modules/connectors.types.js";
104+
export type {
105+
ConnectorsModule,
106+
UserConnectorsModule,
107+
} from "./modules/connectors.types.js";
105108

106109
export type {
107110
CustomIntegrationsModule,

src/modules/connectors.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
ConnectorAccessTokenResponse,
55
ConnectorConnectionResponse,
66
ConnectorsModule,
7+
UserConnectorsModule,
78
} from "./connectors.types.js";
89

910
/**
@@ -58,3 +59,56 @@ export function createConnectorsModule(
5859
},
5960
};
6061
}
62+
63+
/**
64+
* Creates the user-scoped Connectors module (app-user OAuth flows).
65+
*
66+
* @param axios - Axios instance (user-scoped client)
67+
* @param appId - Application ID
68+
* @returns User connectors module with app-user OAuth methods
69+
* @internal
70+
*/
71+
export function createUserConnectorsModule(
72+
axios: AxiosInstance,
73+
appId: string
74+
): UserConnectorsModule {
75+
return {
76+
async getCurrentAppUserAccessToken(
77+
connectorId: string
78+
): Promise<string> {
79+
if (!connectorId || typeof connectorId !== "string") {
80+
throw new Error("Connector ID is required and must be a string");
81+
}
82+
83+
const response = await axios.get(
84+
`/apps/${appId}/app-user-auth/connectors/${connectorId}/token`
85+
);
86+
87+
const data = response as unknown as { access_token: string };
88+
return data.access_token;
89+
},
90+
91+
async connectAppUser(connectorId: string): Promise<string> {
92+
if (!connectorId || typeof connectorId !== "string") {
93+
throw new Error("Connector ID is required and must be a string");
94+
}
95+
96+
const response = await axios.post(
97+
`/apps/${appId}/app-user-auth/connectors/${connectorId}/initiate`
98+
);
99+
100+
const data = response as unknown as { redirect_url: string };
101+
return data.redirect_url;
102+
},
103+
104+
async disconnectAppUser(connectorId: string): Promise<void> {
105+
if (!connectorId || typeof connectorId !== "string") {
106+
throw new Error("Connector ID is required and must be a string");
107+
}
108+
109+
await axios.delete(
110+
`/apps/${appId}/app-user-auth/connectors/${connectorId}`
111+
);
112+
},
113+
};
114+
}

src/modules/connectors.types.ts

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export interface ConnectorConnectionResponse {
3939
}
4040

4141
/**
42-
* Connectors module for managing OAuth tokens for external services.
42+
* Connectors module for managing app-scoped OAuth tokens for external services.
4343
*
4444
* This module allows you to retrieve OAuth access tokens for external services that the app has connected to. Connectors are app-scoped. When an app builder connects an integration like Google Calendar, Slack, or GitHub, all users of the app share that same connection.
4545
*
@@ -233,3 +233,76 @@ export interface ConnectorsModule {
233233
integrationType: ConnectorIntegrationType,
234234
): Promise<ConnectorConnectionResponse>;
235235
}
236+
237+
/**
238+
* User-scoped connectors module for managing app-user OAuth connections.
239+
*
240+
* This module provides methods for app-user OAuth flows: initiating an OAuth connection,
241+
* retrieving the end user's access token, and disconnecting the end user's connection.
242+
*
243+
* Unlike {@link ConnectorsModule | ConnectorsModule} which manages app-scoped tokens,
244+
* this module manages tokens scoped to individual end users. Methods are keyed on
245+
* the connector ID (the OrgConnector's database ID) rather than the integration type.
246+
*
247+
* Available via `base44.connectors`.
248+
*/
249+
export interface UserConnectorsModule {
250+
/**
251+
* Retrieves an OAuth access token for an end user's connection to a specific connector.
252+
*
253+
* Returns the OAuth token string that belongs to the currently authenticated end user
254+
* for the specified connector.
255+
*
256+
* @param connectorId - The connector ID (OrgConnector database ID).
257+
* @returns Promise resolving to the access token string.
258+
*
259+
* @example
260+
* ```typescript
261+
* // Get the end user's access token for a connector
262+
* const token = await base44.connectors.getCurrentAppUserAccessToken('abc123def');
263+
*
264+
* const response = await fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', {
265+
* headers: { 'Authorization': `Bearer ${token}` }
266+
* });
267+
* ```
268+
*/
269+
getCurrentAppUserAccessToken(connectorId: string): Promise<string>;
270+
271+
/**
272+
* Initiates the app-user OAuth flow for a specific connector.
273+
*
274+
* Returns a redirect URL that the end user should be navigated to in order to
275+
* authenticate with the external service. The scopes and integration type are
276+
* derived from the connector configuration server-side.
277+
*
278+
* @param connectorId - The connector ID (OrgConnector database ID).
279+
* @returns Promise resolving to the redirect URL string.
280+
*
281+
* @example
282+
* ```typescript
283+
* // Start OAuth for the end user
284+
* const redirectUrl = await base44.connectors.connectAppUser('abc123def');
285+
*
286+
* // Redirect the user to the OAuth provider
287+
* window.location.href = redirectUrl;
288+
* ```
289+
*/
290+
connectAppUser(connectorId: string): Promise<string>;
291+
292+
/**
293+
* Disconnects an end user's OAuth connection for a specific connector.
294+
*
295+
* Removes the stored OAuth credentials for the currently authenticated end user's
296+
* connection to the specified connector.
297+
*
298+
* @param connectorId - The connector ID (OrgConnector database ID).
299+
* @returns Promise resolving when the connection has been removed.
300+
*
301+
* @example
302+
* ```typescript
303+
* // Disconnect the end user's connection
304+
* await base44.connectors.disconnectAppUser('abc123def');
305+
* ```
306+
*/
307+
disconnectAppUser(connectorId: string): Promise<void>;
308+
}

0 commit comments

Comments
 (0)