diff --git a/API.mcp.md b/API.mcp.md index d4f8fcc..3f7e40b 100644 --- a/API.mcp.md +++ b/API.mcp.md @@ -127,6 +127,22 @@ Retrieves an OAuth 2.1 refresh token. `Promise` — The refresh token record or null. +## `mcp.listAuthorizations` + +*Source: `src/store/mcp/listAuthorizations.js`* + +Lists active authorizations for a Google Auth user. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `googleAuthId` | `number` | The user ID. | + +**Returns** + +`Promise>` — List of authorized clients and token counts. + ## `mcp.listClients` *Source: `src/store/mcp/listClients.js`* @@ -160,6 +176,23 @@ Registers a new OAuth MCP client. `Promise` — The created client record. +## `mcp.revokeAuthorizations` + +*Source: `src/store/mcp/revokeAuthorizations.js`* + +Revokes all active authorizations (tokens) for a user and MCP client. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `googleAuthId` | `number` | The user ID. | +| `clientId` | `string` | The MCP client ID. | + +**Returns** + +`Promise` — True once revoked. + ## `mcp.revokeRefreshToken` *Source: `src/store/mcp/revokeRefreshToken.js`* diff --git a/API.md b/API.md index cf9ae12..42017b3 100644 --- a/API.md +++ b/API.md @@ -315,8 +315,10 @@ The store is exposed as a `LibDashStore` instance (see `src/index.js`). Each met - `getAuthCode(code: string): Promise` - `getClient(clientId: string): Promise` - `getRefreshToken(refreshToken: string): Promise` + - `listAuthorizations(googleAuthId: number): Promise>` - `listClients(): Promise>` - `registerClient(input: {clientId: string, clientSecret?: string|null, clientName: string, redirectUris: string|Array, grantTypes?: string|Array, responseTypes?: string|Array, scope?: string|null}): Promise` + - `revokeAuthorizations(googleAuthId: number, clientId: string): Promise` - `revokeRefreshToken(refreshToken: string): Promise` - [modelconversation](API.modelconversation.md) - `create(googleAuthId: number, input: {provider: string, model: string, started_by?: number|null}, tx?: object): Promise<{id: number, companyuser_id: number, provider: string, model: string, created_at: string, updated_at: string, state: string, started_by: number|null}>` diff --git a/src/index.js b/src/index.js index ec7d64d..fa7b2ee 100644 --- a/src/index.js +++ b/src/index.js @@ -240,6 +240,8 @@ import mcpConsumeAuthCode from './store/mcp/consumeAuthCode.js'; import mcpCreateRefreshToken from './store/mcp/createRefreshToken.js'; import mcpGetRefreshToken from './store/mcp/getRefreshToken.js'; import mcpRevokeRefreshToken from './store/mcp/revokeRefreshToken.js'; +import mcpListAuthorizations from './store/mcp/listAuthorizations.js'; +import mcpRevokeAuthorizations from './store/mcp/revokeAuthorizations.js'; export default class LibDashStore { /** @@ -640,6 +642,8 @@ export default class LibDashStore { createRefreshToken: mcpCreateRefreshToken(provider), getRefreshToken: mcpGetRefreshToken(provider), revokeRefreshToken: mcpRevokeRefreshToken(provider), + listAuthorizations: mcpListAuthorizations(provider), + revokeAuthorizations: mcpRevokeAuthorizations(provider), }; this.purge = storePurge(provider); diff --git a/src/providers/mssql/queries/mcp.js b/src/providers/mssql/queries/mcp.js index 9bf3abb..53c0acc 100644 --- a/src/providers/mssql/queries/mcp.js +++ b/src/providers/mssql/queries/mcp.js @@ -88,3 +88,26 @@ UPDATE mcp_token SET revoked = 1 WHERE refresh_token = @refreshToken `; + +export const LIST_AUTHORIZATIONS_BY_USER = ` +SELECT + c.id AS clientDbId, + c.client_id AS clientId, + c.client_name AS clientName, + c.scope, + c.created_at AS clientCreatedAt, + MAX(t.created_at) AS authorizedAt, + COUNT(t.id) AS tokenCount +FROM mcp_token t +JOIN mcp_client c ON t.client_id = c.client_id +WHERE t.google_auth_id = @googleAuthId AND t.revoked = 0 +GROUP BY c.id, c.client_id, c.client_name, c.scope, c.created_at +ORDER BY MAX(t.created_at) DESC +`; + +export const REVOKE_USER_AUTHORIZATIONS = ` +UPDATE mcp_token +SET revoked = 1 +WHERE google_auth_id = @googleAuthId AND client_id = @clientId +`; + diff --git a/src/providers/sqlite3/queries/mcp.js b/src/providers/sqlite3/queries/mcp.js index 5b3fb69..35066f4 100644 --- a/src/providers/sqlite3/queries/mcp.js +++ b/src/providers/sqlite3/queries/mcp.js @@ -13,4 +13,6 @@ export const { INSERT_REFRESH_TOKEN, GET_REFRESH_TOKEN, REVOKE_REFRESH_TOKEN, + LIST_AUTHORIZATIONS_BY_USER, + REVOKE_USER_AUTHORIZATIONS, } = queries; diff --git a/src/store/mcp/listAuthorizations.js b/src/store/mcp/listAuthorizations.js new file mode 100644 index 0000000..bdd5ea2 --- /dev/null +++ b/src/store/mcp/listAuthorizations.js @@ -0,0 +1,16 @@ +import { LIST_AUTHORIZATIONS_BY_USER as MSSQL_LIST } from '../../providers/mssql/queries/mcp.js'; +import { LIST_AUTHORIZATIONS_BY_USER as SQLITE_LIST } from '../../providers/sqlite3/queries/mcp.js'; + +export default function listAuthorizations(provider) { + const sql = provider.dialect === 'sqlite3' ? SQLITE_LIST : MSSQL_LIST; + /** + * Lists active authorizations for a Google Auth user. + * + * @param {number} googleAuthId - The user ID. + * @returns {Promise>} List of authorized clients and token counts. + */ + return async (googleAuthId) => { + const result = await provider.query(sql, { googleAuthId }); + return result.rows ?? []; + }; +} diff --git a/src/store/mcp/revokeAuthorizations.js b/src/store/mcp/revokeAuthorizations.js new file mode 100644 index 0000000..9137cfd --- /dev/null +++ b/src/store/mcp/revokeAuthorizations.js @@ -0,0 +1,17 @@ +import { REVOKE_USER_AUTHORIZATIONS as MSSQL_REVOKE } from '../../providers/mssql/queries/mcp.js'; +import { REVOKE_USER_AUTHORIZATIONS as SQLITE_REVOKE } from '../../providers/sqlite3/queries/mcp.js'; + +export default function revokeAuthorizations(provider) { + const sql = provider.dialect === 'sqlite3' ? SQLITE_REVOKE : MSSQL_REVOKE; + /** + * Revokes all active authorizations (tokens) for a user and MCP client. + * + * @param {number} googleAuthId - The user ID. + * @param {string} clientId - The MCP client ID. + * @returns {Promise} True once revoked. + */ + return async (googleAuthId, clientId) => { + await provider.query(sql, { googleAuthId, clientId }); + return true; + }; +}