From 66eb3037a3390108901b3ac621efde9c2ea78771 Mon Sep 17 00:00:00 2001 From: Alissa Renz Date: Fri, 10 Nov 2023 18:27:03 -0800 Subject: [PATCH] Add support for apps.manifest.* endpoints (#1690) --- packages/web-api/src/methods.ts | 49 ++++++++ .../response/AppsManifestCreateResponse.ts | 39 +++++++ .../response/AppsManifestDeleteResponse.ts | 17 +++ .../response/AppsManifestExportResponse.ts | 106 ++++++++++++++++++ .../response/AppsManifestUpdateResponse.ts | 19 ++++ .../response/AppsManifestValidateResponse.ts | 29 +++++ .../response/ToolingTokensRotateResponse.ts | 28 +++++ packages/web-api/src/response/index.ts | 6 + .../scripts/apps_manifest_test.js | 76 +++++++++++++ 9 files changed, 369 insertions(+) create mode 100644 packages/web-api/src/response/AppsManifestCreateResponse.ts create mode 100644 packages/web-api/src/response/AppsManifestDeleteResponse.ts create mode 100644 packages/web-api/src/response/AppsManifestExportResponse.ts create mode 100644 packages/web-api/src/response/AppsManifestUpdateResponse.ts create mode 100644 packages/web-api/src/response/AppsManifestValidateResponse.ts create mode 100644 packages/web-api/src/response/ToolingTokensRotateResponse.ts create mode 100644 prod-server-integration-tests/scripts/apps_manifest_test.js diff --git a/packages/web-api/src/methods.ts b/packages/web-api/src/methods.ts index 20b50f20a..fdb7bf7bd 100644 --- a/packages/web-api/src/methods.ts +++ b/packages/web-api/src/methods.ts @@ -84,6 +84,11 @@ import { ApiTestResponse, AppsConnectionsOpenResponse, AppsEventAuthorizationsListResponse, + AppsManifestCreateResponse, + AppsManifestDeleteResponse, + AppsManifestExportResponse, + AppsManifestUpdateResponse, + AppsManifestValidateResponse, AppsUninstallResponse, AuthRevokeResponse, AuthTeamsListResponse, @@ -183,6 +188,7 @@ import { TeamIntegrationLogsResponse, TeamPreferencesListResponse, TeamProfileGetResponse, + ToolingTokensRotateResponse, UsergroupsCreateResponse, UsergroupsDisableResponse, UsergroupsEnableResponse, @@ -535,6 +541,13 @@ export abstract class Methods extends EventEmitter { ), }, }, + manifest: { + create: bindApiCall(this, 'apps.manifest.create'), + delete: bindApiCall(this, 'apps.manifest.delete'), + export: bindApiCall(this, 'apps.manifest.export'), + update: bindApiCall(this, 'apps.manifest.update'), + validate: bindApiCall(this, 'apps.manifest.validate'), + }, uninstall: bindApiCall(this, 'apps.uninstall'), }; @@ -762,6 +775,12 @@ export abstract class Methods extends EventEmitter { }, }; + public readonly tooling = { + tokens: { + rotate: bindApiCall(this, 'tooling.tokens.rotate'), + }, + }; + public readonly usergroups = { create: bindApiCall(this, 'usergroups.create'), disable: bindApiCall(this, 'usergroups.disable'), @@ -1399,6 +1418,29 @@ export interface AppsEventAuthorizationsListArguments event_context: string; } cursorPaginationEnabledMethods.add('apps.event.authorizations.list'); + +export interface AppsManifestCreateArguments extends WebAPICallOptions, TokenOverridable { + manifest: string; +} + +export interface AppsManifestDeleteArguments extends WebAPICallOptions, TokenOverridable { + app_id: string; +} + +export interface AppsManifestExportArguments extends WebAPICallOptions, TokenOverridable { + app_id: string; +} + +export interface AppsManifestUpdateArguments extends WebAPICallOptions, TokenOverridable { + app_id: string; + manifest: string; +} + +export interface AppsManifestValidateArguments extends WebAPICallOptions, TokenOverridable { + app_id?: string; + manifest: string; +} + export interface AppsUninstallArguments extends WebAPICallOptions { client_id: string; client_secret: string; @@ -2300,6 +2342,13 @@ export interface TeamProfileGetArguments extends WebAPICallOptions, TokenOverrid export interface TeamPreferencesListArguments extends WebAPICallOptions, TokenOverridable { } +/* + * `tooling.*` + */ +export interface ToolingTokensRotateArguments extends WebAPICallOptions, TokenOverridable { + refresh_token: string; +} + /* * `usergroups.*` */ diff --git a/packages/web-api/src/response/AppsManifestCreateResponse.ts b/packages/web-api/src/response/AppsManifestCreateResponse.ts new file mode 100644 index 000000000..98f60070f --- /dev/null +++ b/packages/web-api/src/response/AppsManifestCreateResponse.ts @@ -0,0 +1,39 @@ +/* eslint-disable */ +///////////////////////////////////////////////////////////////////////////////////////// +// // +// !!! DO NOT EDIT THIS FILE !!! // +// // +// This file is auto-generated by scripts/generate-web-api-types.sh in the repository. // +// Please refer to the script code to learn how to update the source data. // +// // +///////////////////////////////////////////////////////////////////////////////////////// + +import { WebAPICallResult } from '../WebClient'; +export type AppsManifestCreateResponse = WebAPICallResult & { + app_id?: string; + credentials?: Credentials; + error?: string; + errors?: Error[]; + needed?: string; + oauth_authorize_url?: string; + ok?: boolean; + provided?: string; + response_metadata?: ResponseMetadata; +}; + +export interface Credentials { + client_id?: string; + client_secret?: string; + signing_secret?: string; + verification_token?: string; +} + +export interface Error { + code?: string; + message?: string; + pointer?: string; +} + +export interface ResponseMetadata { + messages?: string[]; +} diff --git a/packages/web-api/src/response/AppsManifestDeleteResponse.ts b/packages/web-api/src/response/AppsManifestDeleteResponse.ts new file mode 100644 index 000000000..36aa5c73d --- /dev/null +++ b/packages/web-api/src/response/AppsManifestDeleteResponse.ts @@ -0,0 +1,17 @@ +/* eslint-disable */ +///////////////////////////////////////////////////////////////////////////////////////// +// // +// !!! DO NOT EDIT THIS FILE !!! // +// // +// This file is auto-generated by scripts/generate-web-api-types.sh in the repository. // +// Please refer to the script code to learn how to update the source data. // +// // +///////////////////////////////////////////////////////////////////////////////////////// + +import { WebAPICallResult } from '../WebClient'; +export type AppsManifestDeleteResponse = WebAPICallResult & { + error?: string; + needed?: string; + ok?: boolean; + provided?: string; +}; diff --git a/packages/web-api/src/response/AppsManifestExportResponse.ts b/packages/web-api/src/response/AppsManifestExportResponse.ts new file mode 100644 index 000000000..b7b005eda --- /dev/null +++ b/packages/web-api/src/response/AppsManifestExportResponse.ts @@ -0,0 +1,106 @@ +/* eslint-disable */ +///////////////////////////////////////////////////////////////////////////////////////// +// // +// !!! DO NOT EDIT THIS FILE !!! // +// // +// This file is auto-generated by scripts/generate-web-api-types.sh in the repository. // +// Please refer to the script code to learn how to update the source data. // +// // +///////////////////////////////////////////////////////////////////////////////////////// + +import { WebAPICallResult } from '../WebClient'; +export type AppsManifestExportResponse = WebAPICallResult & { + error?: string; + manifest?: Manifest; + needed?: string; + ok?: boolean; + provided?: string; +}; + +export interface Manifest { + _metadata?: Metadata; + display_information?: DisplayInformation; + features?: Features; + oauth_config?: OauthConfig; + settings?: Settings; +} + +export interface Metadata { + major_version?: string; + minor_version?: string; +} + +export interface DisplayInformation { + background_color?: string; + description?: string; + long_description?: string; + name?: string; +} + +export interface Features { + app_home?: AppHome; + bot_user?: BotUser; + shortcuts?: Shortcut[]; + slash_commands?: SlashCommand[]; + unfurl_domains?: string[]; +} + +export interface AppHome { + home_tab_enabled?: boolean; + messages_tab_enabled?: boolean; + messages_tab_read_only_enabled?: boolean; +} + +export interface BotUser { + always_online?: boolean; + display_name?: string; +} + +export interface Shortcut { + callback_id?: string; + description?: string; + name?: string; + type?: string; +} + +export interface SlashCommand { + command?: string; + description?: string; + should_escape?: boolean; + url?: string; + usage_hint?: string; +} + +export interface OauthConfig { + redirect_urls?: string[]; + scopes?: Scopes; +} + +export interface Scopes { + bot?: string[]; + user?: string[]; +} + +export interface Settings { + allowed_ip_address_ranges?: string[]; + background_color?: string; + description?: string; + event_subscriptions?: EventSubscriptions; + interactivity?: Interactivity; + long_description?: string; + org_deploy_enabled?: boolean; + socket_mode_enabled?: boolean; + token_rotation_enabled?: boolean; +} + +export interface EventSubscriptions { + bot_events?: string[]; + request_url?: string; + user_events?: string[]; +} + +export interface Interactivity { + is_enabled?: boolean; + message_menu_options_url?: string; + request_url?: string; +} diff --git a/packages/web-api/src/response/AppsManifestUpdateResponse.ts b/packages/web-api/src/response/AppsManifestUpdateResponse.ts new file mode 100644 index 000000000..7b0498454 --- /dev/null +++ b/packages/web-api/src/response/AppsManifestUpdateResponse.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ +///////////////////////////////////////////////////////////////////////////////////////// +// // +// !!! DO NOT EDIT THIS FILE !!! // +// // +// This file is auto-generated by scripts/generate-web-api-types.sh in the repository. // +// Please refer to the script code to learn how to update the source data. // +// // +///////////////////////////////////////////////////////////////////////////////////////// + +import { WebAPICallResult } from '../WebClient'; +export type AppsManifestUpdateResponse = WebAPICallResult & { + app_id?: string; + error?: string; + needed?: string; + ok?: boolean; + permissions_updated?: boolean; + provided?: string; +}; diff --git a/packages/web-api/src/response/AppsManifestValidateResponse.ts b/packages/web-api/src/response/AppsManifestValidateResponse.ts new file mode 100644 index 000000000..fb955dc86 --- /dev/null +++ b/packages/web-api/src/response/AppsManifestValidateResponse.ts @@ -0,0 +1,29 @@ +/* eslint-disable */ +///////////////////////////////////////////////////////////////////////////////////////// +// // +// !!! DO NOT EDIT THIS FILE !!! // +// // +// This file is auto-generated by scripts/generate-web-api-types.sh in the repository. // +// Please refer to the script code to learn how to update the source data. // +// // +///////////////////////////////////////////////////////////////////////////////////////// + +import { WebAPICallResult } from '../WebClient'; +export type AppsManifestValidateResponse = WebAPICallResult & { + error?: string; + errors?: Error[]; + needed?: string; + ok?: boolean; + provided?: string; + response_metadata?: ResponseMetadata; +}; + +export interface Error { + code?: string; + message?: string; + pointer?: string; +} + +export interface ResponseMetadata { + messages?: string[]; +} diff --git a/packages/web-api/src/response/ToolingTokensRotateResponse.ts b/packages/web-api/src/response/ToolingTokensRotateResponse.ts new file mode 100644 index 000000000..093f088d5 --- /dev/null +++ b/packages/web-api/src/response/ToolingTokensRotateResponse.ts @@ -0,0 +1,28 @@ +/* eslint-disable */ +///////////////////////////////////////////////////////////////////////////////////////// +// // +// !!! DO NOT EDIT THIS FILE !!! // +// // +// This file is auto-generated by scripts/generate-web-api-types.sh in the repository. // +// Please refer to the script code to learn how to update the source data. // +// // +///////////////////////////////////////////////////////////////////////////////////////// + +import { WebAPICallResult } from '../WebClient'; +export type ToolingTokensRotateResponse = WebAPICallResult & { + error?: string; + exp?: number; + iat?: number; + needed?: string; + ok?: boolean; + provided?: string; + refresh_token?: string; + response_metadata?: ResponseMetadata; + team_id?: string; + token?: string; + user_id?: string; +}; + +export interface ResponseMetadata { + messages?: string[]; +} diff --git a/packages/web-api/src/response/index.ts b/packages/web-api/src/response/index.ts index 62dd725f2..d7d710d6c 100644 --- a/packages/web-api/src/response/index.ts +++ b/packages/web-api/src/response/index.ts @@ -99,6 +99,11 @@ export { AdminWorkflowsUnpublishResponse } from './AdminWorkflowsUnpublishRespon export { ApiTestResponse } from './ApiTestResponse'; export { AppsConnectionsOpenResponse } from './AppsConnectionsOpenResponse'; export { AppsEventAuthorizationsListResponse } from './AppsEventAuthorizationsListResponse'; +export { AppsManifestCreateResponse } from './AppsManifestCreateResponse'; +export { AppsManifestDeleteResponse } from './AppsManifestDeleteResponse'; +export { AppsManifestExportResponse } from './AppsManifestExportResponse'; +export { AppsManifestUpdateResponse } from './AppsManifestUpdateResponse'; +export { AppsManifestValidateResponse } from './AppsManifestValidateResponse'; export { AppsPermissionsInfoResponse } from './AppsPermissionsInfoResponse'; export { AppsPermissionsRequestResponse } from './AppsPermissionsRequestResponse'; export { AppsPermissionsResourcesListResponse } from './AppsPermissionsResourcesListResponse'; @@ -255,6 +260,7 @@ export { TeamInfoResponse } from './TeamInfoResponse'; export { TeamIntegrationLogsResponse } from './TeamIntegrationLogsResponse'; export { TeamPreferencesListResponse } from './TeamPreferencesListResponse'; export { TeamProfileGetResponse } from './TeamProfileGetResponse'; +export { ToolingTokensRotateResponse } from './ToolingTokensRotateResponse'; export { UsergroupsCreateResponse } from './UsergroupsCreateResponse'; export { UsergroupsDisableResponse } from './UsergroupsDisableResponse'; export { UsergroupsEnableResponse } from './UsergroupsEnableResponse'; diff --git a/prod-server-integration-tests/scripts/apps_manifest_test.js b/prod-server-integration-tests/scripts/apps_manifest_test.js new file mode 100644 index 000000000..20788485a --- /dev/null +++ b/prod-server-integration-tests/scripts/apps_manifest_test.js @@ -0,0 +1,76 @@ +const { WebClient } = require('@slack/web-api'); + +const options = {}; + +const TOOLING_TOKEN = process.env.SLACK_TOOLING_TOKEN; + +if (process.env.SLACK_SDK_TEST_DEV_API_URL !== undefined) { + options.slackApiUrl = process.env.SLACK_SDK_TEST_DEV_API_URL; +} + +const client = new WebClient(options); + +(async () => { + const manifest = `{ + "_metadata": { + "major_version": 1, + "minor_version": 1 + }, + "display_information": { + "name": "Test Manifest App" + }, + "features": { + "bot_user": { + "display_name": "Test Manifest App", + "always_online": false + } + }, + "oauth_config": { + "scopes": { + "bot": [ + "channels:history" + ] + } + }, + "settings": { + "event_subscriptions": { + "request_url": "https://yourhosthere.ngrok.io/slack/events", + "bot_events": [ + "message.channels" + ] + }, + "org_deploy_enabled": false, + "socket_mode_enabled": false, + "is_hosted": false, + "token_rotation_enabled": false + } + }`; + + let appId; + + try { + + // Verify a manifest is valid + const validateRes = await client.apps.manifest.validate({ token: TOOLING_TOKEN, manifest }); + console.log(JSON.stringify(validateRes, null, 2)); + + // Create a new app using a manifest + const createRes = await client.apps.manifest.create({ token: TOOLING_TOKEN, manifest }); + appId = createRes.app_id + console.log(JSON.stringify(createRes, null, 2)); + + // Update the app using an altered manifest + const updatedManifest = { ...JSON.parse(manifest), display_information: { name: 'Updated Test Manifest App' } }; + const updateRes = await client.apps.manifest.update({ token: TOOLING_TOKEN, app_id: appId, manifest: updatedManifest }); + console.log(JSON.stringify(updateRes, null, 2)); + + // Export (get) the app's manifest + const exportRes = await client.apps.manifest.export({ token: TOOLING_TOKEN, app_id: appId }); + console.log(JSON.stringify(exportRes, null, 2)); + + } finally { + // Delete the app + const deleteRes = await client.apps.manifest.delete({ token: TOOLING_TOKEN, app_id: appId }); + console.log(JSON.stringify(deleteRes, null, 2)); + }; +})(); \ No newline at end of file