diff --git a/openapi.json b/openapi.json index a83f1542..5e47283a 100644 --- a/openapi.json +++ b/openapi.json @@ -67,6 +67,9 @@ }, { "name": "Deprecated" + }, + { + "name": "Telemetry" } ], "components": { @@ -34752,6 +34755,8 @@ "security-policy:read", "socket-basics", "socket-basics:read", + "telemetry-policy", + "telemetry-policy:update", "threat-feed", "threat-feed:list", "triage", @@ -35106,6 +35111,8 @@ "security-policy:read", "socket-basics", "socket-basics:read", + "telemetry-policy", + "telemetry-policy:update", "threat-feed", "threat-feed:list", "triage", @@ -35277,6 +35284,8 @@ "security-policy:read", "socket-basics", "socket-basics:read", + "telemetry-policy", + "telemetry-policy:update", "threat-feed", "threat-feed:list", "triage", @@ -37338,6 +37347,185 @@ "x-readme": {} } }, + "/orgs/{org_slug}/telemetry/config": { + "get": { + "tags": [ + "Telemetry" + ], + "summary": "Get Organization Telemetry Config", + "operationId": "getOrgTelemetryConfig", + "parameters": [ + { + "name": "org_slug", + "in": "path", + "required": true, + "description": "The slug of the organization", + "schema": { + "type": "string" + } + } + ], + "security": [ + { + "bearerAuth": [] + }, + { + "basicAuth": [] + } + ], + "description": "Retrieve the telemetry config of an organization.\n\nThis endpoint consumes 1 unit of your quota.\n\nThis endpoint requires the following org token scopes:", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "description": "", + "properties": { + "telemetry": { + "type": "object", + "additionalProperties": false, + "description": "Telemetry configuration", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Telemetry enabled" + } + }, + "required": [ + "enabled" + ] + } + }, + "required": [ + "telemetry" + ] + } + } + }, + "description": "Retrieved telemetry config details" + }, + "400": { + "$ref": "#/components/responses/SocketBadRequest" + }, + "401": { + "$ref": "#/components/responses/SocketUnauthorized" + }, + "403": { + "$ref": "#/components/responses/SocketForbidden" + }, + "404": { + "$ref": "#/components/responses/SocketNotFoundResponse" + }, + "429": { + "$ref": "#/components/responses/SocketTooManyRequestsResponse" + } + }, + "x-readme": {} + }, + "put": { + "tags": [ + "Telemetry" + ], + "summary": "Update Telemetry Config", + "operationId": "updateOrgTelemetryConfig", + "parameters": [ + { + "name": "org_slug", + "in": "path", + "required": true, + "description": "The slug of the organization", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Telemetry enabled" + } + }, + "description": "" + } + } + }, + "required": false + }, + "security": [ + { + "bearerAuth": [ + "telemetry-policy:update" + ] + }, + { + "basicAuth": [ + "telemetry-policy:update" + ] + } + ], + "description": "Update the telemetry config of an organization.\n\nThis endpoint consumes 1 unit of your quota.\n\nThis endpoint requires the following org token scopes:\n- telemetry-policy:update", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "description": "", + "properties": { + "telemetry": { + "type": "object", + "additionalProperties": false, + "description": "Telemetry configuration", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Telemetry enabled" + } + }, + "required": [ + "enabled" + ] + } + }, + "required": [ + "telemetry" + ] + } + } + }, + "description": "Updated telemetry config details" + }, + "400": { + "$ref": "#/components/responses/SocketBadRequest" + }, + "401": { + "$ref": "#/components/responses/SocketUnauthorized" + }, + "403": { + "$ref": "#/components/responses/SocketForbidden" + }, + "404": { + "$ref": "#/components/responses/SocketNotFoundResponse" + }, + "429": { + "$ref": "#/components/responses/SocketTooManyRequestsResponse" + } + }, + "x-readme": {} + } + }, "/orgs/{org_slug}/webhooks": { "get": { "tags": [ diff --git a/src/index.ts b/src/index.ts index 13be7246..fcc32803 100644 --- a/src/index.ts +++ b/src/index.ts @@ -74,6 +74,9 @@ export type { PatchFile, PatchRecord, PatchViewResponse, + TelemetryConfig, + PostOrgTelemetryPayload, + PostOrgTelemetryResponse, QueryParams, RequestInfo, RequestOptions, diff --git a/src/socket-sdk-class.ts b/src/socket-sdk-class.ts index 06da2b46..2eeb14e2 100644 --- a/src/socket-sdk-class.ts +++ b/src/socket-sdk-class.ts @@ -73,6 +73,8 @@ import type { GetOptions, GotOptions, PatchViewResponse, + PostOrgTelemetryPayload, + PostOrgTelemetryResponse, QueryParams, RequestOptions, SendOptions, @@ -3481,6 +3483,113 @@ export class SocketSdk { }) }) } + + /** + * Update organization's telemetry configuration. + * Enables or disables telemetry for the organization. + * + * @param orgSlug - Organization identifier + * @param telemetryData - Telemetry configuration with enabled flag + * @returns Updated telemetry configuration + * + * @throws {Error} When server returns 5xx status codes + */ + async updateOrgTelemetryConfig( + orgSlug: string, + telemetryData: { enabled?: boolean | undefined }, + ): Promise> { + try { + const data = await this.#executeWithRetry( + async () => + await getResponseJson( + await createRequestWithJson( + 'PUT', + this.#baseUrl, + `orgs/${encodeURIComponent(orgSlug)}/telemetry/config`, + telemetryData, + this.#reqOptions, + ), + ), + ) + return this.#handleApiSuccess<'updateOrgTelemetryConfig'>(data) + /* c8 ignore start - Standard API error handling, tested via public method error cases */ + } catch (e) { + return await this.#handleApiError<'updateOrgTelemetryConfig'>(e) + } + /* c8 ignore stop */ + } + + /** + * Get organization's telemetry configuration. + * Returns whether telemetry is enabled for the organization. + * + * @param orgSlug - Organization identifier + * @returns Telemetry configuration with enabled status + * + * @throws {Error} When server returns 5xx status codes + */ + async getTelemetryConfig( + orgSlug: string, + ): Promise> { + try { + const data = await this.#executeWithRetry( + async () => + await getResponseJson( + await createGetRequest( + this.#baseUrl, + `orgs/${encodeURIComponent(orgSlug)}/telemetry/config`, + this.#reqOptions, + ), + ), + ) + return this.#handleApiSuccess<'getOrgTelemetryConfig'>(data) + /* c8 ignore start - Standard API error handling, tested via public method error cases */ + } catch (e) { + return await this.#handleApiError<'getOrgTelemetryConfig'>(e) + } + /* c8 ignore stop */ + } + + /** + * Post telemetry data for an organization. + * Sends telemetry events and analytics data for monitoring and analysis. + * + * @param orgSlug - Organization identifier + * @param telemetryData - Telemetry payload containing events and metrics + * @returns Empty object on successful submission + * + * @throws {Error} When server returns 5xx status codes + */ + async postOrgTelemetry( + orgSlug: string, + telemetryData: PostOrgTelemetryPayload, + ): Promise> { + try { + const data = (await this.#executeWithRetry( + async () => + await getResponseJson( + await createRequestWithJson( + 'POST', + this.#baseUrl, + `orgs/${encodeURIComponent(orgSlug)}/telemetry`, + telemetryData, + this.#reqOptions, + ), + ), + )) as PostOrgTelemetryResponse + return { + cause: undefined, + data, + error: undefined, + status: 200, + success: true, + } + /* c8 ignore start - Standard API error handling, tested via public method error cases */ + } catch (e) { + return this.#createQueryErrorResult(e) + } + /* c8 ignore stop */ + } } // Optional live heap trace. diff --git a/src/types.ts b/src/types.ts index aff78d88..4087f9b5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -423,6 +423,20 @@ export type StreamOrgFullScanOptions = { output?: boolean | string | undefined } +export type PostOrgTelemetryPayload = Record + +export type PostOrgTelemetryResponse = Record + +/** + * Configuration for telemetry collection. + * Controls whether telemetry is enabled and how events are collected. + */ +export interface TelemetryConfig { + telemetry: { + enabled: boolean + } +} + export type UploadManifestFilesOptions = { pathsRelativeTo?: string | undefined } diff --git a/test/unit/socket-sdk-api-methods.coverage.test.mts b/test/unit/socket-sdk-api-methods.coverage.test.mts index 4070c938..da7103c7 100644 --- a/test/unit/socket-sdk-api-methods.coverage.test.mts +++ b/test/unit/socket-sdk-api-methods.coverage.test.mts @@ -152,6 +152,20 @@ describe('SocketSdk - API Methods Coverage', () => { } else if (url.includes('/quota')) { // Quota endpoint res.end(JSON.stringify({ data: { limit: 1000, used: 100 } })) + } else if (url.includes('/telemetry/config')) { + // Telemetry config endpoint + if (req.method === 'PUT') { + res.end(JSON.stringify({ telemetry: { enabled: true } })) + } else { + res.end(JSON.stringify({ telemetry: { enabled: false } })) + } + } else if (url.includes('/telemetry')) { + // Telemetry POST endpoint (must come before generic /settings) + if (req.method === 'POST') { + res.end(JSON.stringify({})) + } else { + res.end(JSON.stringify({})) + } } else if (url.includes('/settings')) { // Settings endpoint res.end(JSON.stringify({ data: { success: true } })) @@ -492,6 +506,42 @@ describe('SocketSdk - API Methods Coverage', () => { }) }) + describe('Telemetry Methods', () => { + it('covers getTelemetryConfig', async () => { + const result = await client.getTelemetryConfig('test-org') + expect(result.success).toBe(true) + if (result.success) { + expect(result.data).toBeDefined() + expect(result.data.telemetry).toBeDefined() + expect(result.data.telemetry.enabled).toBe(false) + } + }) + + it('covers updateOrgTelemetryConfig', async () => { + const result = await client.updateOrgTelemetryConfig('test-org', { + enabled: true, + }) + expect(result.success).toBe(true) + if (result.success) { + expect(result.data).toBeDefined() + expect(result.data.telemetry).toBeDefined() + expect(result.data.telemetry.enabled).toBe(true) + } + }) + + it('covers postOrgTelemetry', async () => { + const result = await client.postOrgTelemetry('test-org', { + event: 'test-event', + timestamp: Date.now(), + }) + expect(result.success).toBe(true) + if (result.success) { + expect(result.data).toBeDefined() + expect(result.data).toEqual({}) + } + }) + }) + describe('API Token Methods', () => { it('covers getAPITokens', async () => { const result = await client.getAPITokens('test-org') diff --git a/types/api.d.ts b/types/api.d.ts index e37291c2..db57cc19 100644 --- a/types/api.d.ts +++ b/types/api.d.ts @@ -943,6 +943,27 @@ export interface paths { */ get: operations['fetch-fixes'] } + '/orgs/{org_slug}/telemetry/config': { + /** + * Get Organization Telemetry Config + * @description Retrieve the telemetry config of an organization. + * + * This endpoint consumes 1 unit of your quota. + * + * This endpoint requires the following org token scopes: + */ + get: operations['getOrgTelemetryConfig'] + /** + * Update Telemetry Config + * @description Update the telemetry config of an organization. + * + * This endpoint consumes 1 unit of your quota. + * + * This endpoint requires the following org token scopes: + * - telemetry-policy:update + */ + put: operations['updateOrgTelemetryConfig'] + } '/orgs/{org_slug}/webhooks': { /** * List all webhooks @@ -13823,6 +13844,8 @@ export interface operations { | 'security-policy:read' | 'socket-basics' | 'socket-basics:read' + | 'telemetry-policy' + | 'telemetry-policy:update' | 'threat-feed' | 'threat-feed:list' | 'triage' @@ -13941,6 +13964,8 @@ export interface operations { | 'security-policy:read' | 'socket-basics' | 'socket-basics:read' + | 'telemetry-policy' + | 'telemetry-policy:update' | 'threat-feed' | 'threat-feed:list' | 'triage' @@ -14079,6 +14104,8 @@ export interface operations { | 'security-policy:read' | 'socket-basics' | 'socket-basics:read' + | 'telemetry-policy' + | 'telemetry-policy:update' | 'threat-feed' | 'threat-feed:list' | 'triage' @@ -14906,6 +14933,94 @@ export interface operations { 429: components['responses']['SocketTooManyRequestsResponse'] } } + /** + * Get Organization Telemetry Config + * @description Retrieve the telemetry config of an organization. + * + * This endpoint consumes 1 unit of your quota. + * + * This endpoint requires the following org token scopes: + */ + getOrgTelemetryConfig: { + parameters: { + path: { + /** @description The slug of the organization */ + org_slug: string + } + } + responses: { + /** @description Retrieved telemetry config details */ + 200: { + content: { + 'application/json': { + /** @description Telemetry configuration */ + telemetry: { + /** + * @description Telemetry enabled + * @default false + */ + enabled: boolean + } + } + } + } + 400: components['responses']['SocketBadRequest'] + 401: components['responses']['SocketUnauthorized'] + 403: components['responses']['SocketForbidden'] + 404: components['responses']['SocketNotFoundResponse'] + 429: components['responses']['SocketTooManyRequestsResponse'] + } + } + /** + * Update Telemetry Config + * @description Update the telemetry config of an organization. + * + * This endpoint consumes 1 unit of your quota. + * + * This endpoint requires the following org token scopes: + * - telemetry-policy:update + */ + updateOrgTelemetryConfig: { + parameters: { + path: { + /** @description The slug of the organization */ + org_slug: string + } + } + requestBody?: { + content: { + 'application/json': { + /** + * @description Telemetry enabled + * @default false + */ + enabled?: boolean + } + } + } + responses: { + /** @description Updated telemetry config details */ + 200: { + content: { + 'application/json': { + /** @description Telemetry configuration */ + telemetry: { + /** + * @description Telemetry enabled + * @default false + */ + enabled: boolean + } + } + } + } + 400: components['responses']['SocketBadRequest'] + 401: components['responses']['SocketUnauthorized'] + 403: components['responses']['SocketForbidden'] + 404: components['responses']['SocketNotFoundResponse'] + 429: components['responses']['SocketTooManyRequestsResponse'] + } + } /** * List all webhooks * @description List all webhooks in the specified organization.