From 7e2bdddbfa7b491fde87371cad5f3723308d19d7 Mon Sep 17 00:00:00 2001 From: Raymond Jacobson Date: Fri, 13 Feb 2026 16:49:13 -0800 Subject: [PATCH] Update dev apps, add grants --- .../developer-apps/useAddDeveloperApp.ts | 27 +- .../developer-apps/useDeveloperApps.ts | 2 +- packages/common/src/schemas/developerApps.ts | 1 + .../api/developer-apps/DeveloperAppsApi.ts | 2 +- .../default/.openapi-generator/FILES | 7 +- .../default/apis/DeveloperAppsApi.ts | 213 +++++++---- .../api/generated/default/apis/UsersApi.ts | 349 +++++++++--------- .../default/models/AddManagerRequestBody.ts | 67 ++++ .../default/models/ApproveGrantRequestBody.ts | 67 ++++ .../models/CreateDeveloperAppRequestBody.ts | 28 +- ...eateDeveloperAppRequestBodyAppSignature.ts | 76 ---- .../models/CreateDeveloperAppResponse.ts | 90 +++++ .../default/models/CreateGrantRequestBody.ts | 67 ++++ .../models/CreateUserDeveloperAppResponse.ts | 10 +- .../default/models/PinCommentRequestBody.ts | 16 + .../models/UpdateDeveloperAppRequestBody.ts | 10 +- .../sdk/api/generated/default/models/index.ts | 5 +- packages/sdk/src/sdk/api/grants/GrantsApi.ts | 231 ++++++++---- .../desktop/DeveloperApps/AppDetailsPage.tsx | 40 +- 19 files changed, 868 insertions(+), 440 deletions(-) create mode 100644 packages/sdk/src/sdk/api/generated/default/models/AddManagerRequestBody.ts create mode 100644 packages/sdk/src/sdk/api/generated/default/models/ApproveGrantRequestBody.ts delete mode 100644 packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppRequestBodyAppSignature.ts create mode 100644 packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppResponse.ts create mode 100644 packages/sdk/src/sdk/api/generated/default/models/CreateGrantRequestBody.ts diff --git a/packages/common/src/api/tan-query/developer-apps/useAddDeveloperApp.ts b/packages/common/src/api/tan-query/developer-apps/useAddDeveloperApp.ts index 210c7bef9ee..d36b99a16bf 100644 --- a/packages/common/src/api/tan-query/developer-apps/useAddDeveloperApp.ts +++ b/packages/common/src/api/tan-query/developer-apps/useAddDeveloperApp.ts @@ -22,25 +22,40 @@ export const useAddDeveloperApp = () => { const encodedUserId = Id.parse(currentUserId) const sdk = await audiusSdk() - const { apiKey, apiSecret } = await sdk.developerApps.createDeveloperApp({ - name, - description, - imageUrl, + const result = await sdk.developerApps.createDeveloperApp({ + metadata: { + name, + description, + imageUrl + }, userId: encodedUserId }) + const { apiKey, apiSecret } = result + const bearerToken = + 'bearerToken' in result && typeof result.bearerToken === 'string' + ? result.bearerToken + : undefined + + if (!apiKey || !apiSecret) { + throw new Error('Failed to create developer app') + } await sdk.grants.createGrant({ userId: encodedUserId, appApiKey: apiKey }) - return { name, description, imageUrl, apiKey, apiSecret } + return { name, description, imageUrl, apiKey, apiSecret, bearerToken } }, onSuccess: (newApp: DeveloperApp) => { if (!currentUserId) { throw new Error('No current user ID') } - const { apiSecret: apiSecretIgnored, ...restNewApp } = newApp + const { + apiSecret: apiSecretIgnored, + bearerToken: bearerTokenIgnored, + ...restNewApp + } = newApp queryClient.setQueryData( getDeveloperAppsQueryKey(currentUserId), diff --git a/packages/common/src/api/tan-query/developer-apps/useDeveloperApps.ts b/packages/common/src/api/tan-query/developer-apps/useDeveloperApps.ts index d7454f5b7ac..55f0994067a 100644 --- a/packages/common/src/api/tan-query/developer-apps/useDeveloperApps.ts +++ b/packages/common/src/api/tan-query/developer-apps/useDeveloperApps.ts @@ -25,7 +25,7 @@ export const useDeveloperApps = ( queryKey: getDeveloperAppsQueryKey(userId), queryFn: async () => { const sdk = await audiusSdk() - const { data = [] } = await sdk.users.getDeveloperApps({ + const { data = [] } = await sdk.developerApps.getDeveloperApps({ id: Id.parse(userId) }) diff --git a/packages/common/src/schemas/developerApps.ts b/packages/common/src/schemas/developerApps.ts index 6976c8dda46..b0b045ffc74 100644 --- a/packages/common/src/schemas/developerApps.ts +++ b/packages/common/src/schemas/developerApps.ts @@ -15,6 +15,7 @@ export type DeveloperApp = { imageUrl?: string apiKey: string apiSecret?: string + bearerToken?: string } export const developerAppSchema = z.object({ diff --git a/packages/sdk/src/sdk/api/developer-apps/DeveloperAppsApi.ts b/packages/sdk/src/sdk/api/developer-apps/DeveloperAppsApi.ts index 6548b279708..5717659cef1 100644 --- a/packages/sdk/src/sdk/api/developer-apps/DeveloperAppsApi.ts +++ b/packages/sdk/src/sdk/api/developer-apps/DeveloperAppsApi.ts @@ -90,7 +90,7 @@ export class DeveloperAppsApi extends GeneratedDeveloperAppsApi { ) { if (this.entityManager) { return await this.createDeveloperAppWithEntityManager({ - ...params.createDeveloperAppRequestBody, + ...params.metadata, userId: params.userId }) } else { diff --git a/packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES b/packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES index 0e60311f3de..efe91155c38 100644 --- a/packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES +++ b/packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES @@ -20,8 +20,10 @@ models/Access.ts models/AccessGate.ts models/AccessInfoResponse.ts models/Activity.ts +models/AddManagerRequestBody.ts models/AlbumBacklink.ts models/AlbumsResponse.ts +models/ApproveGrantRequestBody.ts models/AuthorizedApp.ts models/AuthorizedApps.ts models/BalanceHistoryDataPoint.ts @@ -69,7 +71,8 @@ models/CreateCoinResponseData.ts models/CreateCommentRequestBody.ts models/CreateCommentResponse.ts models/CreateDeveloperAppRequestBody.ts -models/CreateDeveloperAppRequestBodyAppSignature.ts +models/CreateDeveloperAppResponse.ts +models/CreateGrantRequestBody.ts models/CreatePlaylistRequestBody.ts models/CreatePlaylistResponse.ts models/CreateRewardCodeRequestBody.ts @@ -114,6 +117,7 @@ models/MediaLink.ts models/MonthlyAggregatePlay.ts models/Mood.ts models/MutualFollowersResponse.ts +models/PinCommentRequestBody.ts models/Playlist.ts models/PlaylistAddedTimestamp.ts models/PlaylistArtwork.ts @@ -127,6 +131,7 @@ models/PrizePublic.ts models/PrizesResponse.ts models/ProfilePicture.ts models/PurchasersResponse.ts +models/ReactCommentRequestBody.ts models/RedeemAmountResponse.ts models/RelatedArtistResponse.ts models/RemixParent.ts diff --git a/packages/sdk/src/sdk/api/generated/default/apis/DeveloperAppsApi.ts b/packages/sdk/src/sdk/api/generated/default/apis/DeveloperAppsApi.ts index eb00ffc8304..382600d8f6a 100644 --- a/packages/sdk/src/sdk/api/generated/default/apis/DeveloperAppsApi.ts +++ b/packages/sdk/src/sdk/api/generated/default/apis/DeveloperAppsApi.ts @@ -16,18 +16,30 @@ import * as runtime from '../runtime'; import type { + CreateAccessKeyResponse, CreateDeveloperAppRequestBody, + CreateDeveloperAppResponse, + DeactivateAccessKeyRequestBody, + DeactivateAccessKeyResponse, DeveloperAppResponse, - UpdateDeveloperAppRequestBody, + DeveloperAppsResponse, WriteResponse, } from '../models'; import { + CreateAccessKeyResponseFromJSON, + CreateAccessKeyResponseToJSON, CreateDeveloperAppRequestBodyFromJSON, CreateDeveloperAppRequestBodyToJSON, + CreateDeveloperAppResponseFromJSON, + CreateDeveloperAppResponseToJSON, + DeactivateAccessKeyRequestBodyFromJSON, + DeactivateAccessKeyRequestBodyToJSON, + DeactivateAccessKeyResponseFromJSON, + DeactivateAccessKeyResponseToJSON, DeveloperAppResponseFromJSON, DeveloperAppResponseToJSON, - UpdateDeveloperAppRequestBodyFromJSON, - UpdateDeveloperAppRequestBodyToJSON, + DeveloperAppsResponseFromJSON, + DeveloperAppsResponseToJSON, WriteResponseFromJSON, WriteResponseToJSON, } from '../models'; @@ -37,19 +49,29 @@ export interface CreateDeveloperAppRequest { metadata: CreateDeveloperAppRequestBody; } -export interface DeleteDeveloperAppRequest { +export interface CreateDeveloperAppAccessKeyRequest { + userId: string; address: string; +} + +export interface DeactivateDeveloperAppAccessKeyRequest { userId: string; + address: string; + metadata: DeactivateAccessKeyRequestBody; } -export interface GetDeveloperAppRequest { +export interface DeleteDeveloperAppRequest { + userId: string; address: string; } -export interface UpdateDeveloperAppRequest { +export interface GetDeveloperAppRequest { address: string; - userId: string; - metadata: UpdateDeveloperAppRequestBody; +} + +export interface GetDeveloperAppsRequest { + id: string; + include?: GetDeveloperAppsIncludeEnum; } /** @@ -59,9 +81,9 @@ export class DeveloperAppsApi extends runtime.BaseAPI { /** * @hidden - * Creates a new developer app + * Create a new developer app (Plans API). Indexer validates grants. */ - async createDeveloperAppRaw(params: CreateDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + async createDeveloperAppRaw(params: CreateDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { if (params.userId === null || params.userId === undefined) { throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling createDeveloperApp.'); } @@ -80,17 +102,6 @@ export class DeveloperAppsApi extends runtime.BaseAPI { headerParameters['Content-Type'] = 'application/json'; - if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) { - headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password); - } - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("BearerAuth", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } const response = await this.request({ path: `/developer-apps`, method: 'POST', @@ -99,28 +110,71 @@ export class DeveloperAppsApi extends runtime.BaseAPI { body: CreateDeveloperAppRequestBodyToJSON(params.metadata), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => WriteResponseFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => CreateDeveloperAppResponseFromJSON(jsonValue)); } /** - * Creates a new developer app + * Create a new developer app (Plans API). Indexer validates grants. */ - async createDeveloperApp(params: CreateDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + async createDeveloperApp(params: CreateDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { const response = await this.createDeveloperAppRaw(params, initOverrides); return await response.value(); } /** * @hidden - * Deletes a developer app + * Create a new bearer token (API access key) for a developer app (Plans API). Indexer validates grants. */ - async deleteDeveloperAppRaw(params: DeleteDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + async createDeveloperAppAccessKeyRaw(params: CreateDeveloperAppAccessKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.userId === null || params.userId === undefined) { + throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling createDeveloperAppAccessKey.'); + } + if (params.address === null || params.address === undefined) { - throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling deleteDeveloperApp.'); + throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling createDeveloperAppAccessKey.'); + } + + const queryParameters: any = {}; + + if (params.userId !== undefined) { + queryParameters['user_id'] = params.userId; } + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/developer-apps/{address}/access-keys`.replace(`{${"address"}}`, encodeURIComponent(String(params.address))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateAccessKeyResponseFromJSON(jsonValue)); + } + + /** + * Create a new bearer token (API access key) for a developer app (Plans API). Indexer validates grants. + */ + async createDeveloperAppAccessKey(params: CreateDeveloperAppAccessKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createDeveloperAppAccessKeyRaw(params, initOverrides); + return await response.value(); + } + + /** + * @hidden + * Deactivate a bearer token (API access key) for a developer app (Plans API). Indexer validates grants. + */ + async deactivateDeveloperAppAccessKeyRaw(params: DeactivateDeveloperAppAccessKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { if (params.userId === null || params.userId === undefined) { - throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling deleteDeveloperApp.'); + throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling deactivateDeveloperAppAccessKey.'); + } + + if (params.address === null || params.address === undefined) { + throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling deactivateDeveloperAppAccessKey.'); + } + + if (params.metadata === null || params.metadata === undefined) { + throw new runtime.RequiredError('metadata','Required parameter params.metadata was null or undefined when calling deactivateDeveloperAppAccessKey.'); } const queryParameters: any = {}; @@ -131,17 +185,48 @@ export class DeveloperAppsApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) { - headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password); + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/developer-apps/{address}/access-keys/deactivate`.replace(`{${"address"}}`, encodeURIComponent(String(params.address))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: DeactivateAccessKeyRequestBodyToJSON(params.metadata), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => DeactivateAccessKeyResponseFromJSON(jsonValue)); + } + + /** + * Deactivate a bearer token (API access key) for a developer app (Plans API). Indexer validates grants. + */ + async deactivateDeveloperAppAccessKey(params: DeactivateDeveloperAppAccessKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.deactivateDeveloperAppAccessKeyRaw(params, initOverrides); + return await response.value(); + } + + /** + * @hidden + * Deletes a developer app (Plans API). Indexer validates grants. + */ + async deleteDeveloperAppRaw(params: DeleteDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.userId === null || params.userId === undefined) { + throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling deleteDeveloperApp.'); + } + + if (params.address === null || params.address === undefined) { + throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling deleteDeveloperApp.'); } - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("BearerAuth", []); - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } + const queryParameters: any = {}; + + if (params.userId !== undefined) { + queryParameters['user_id'] = params.userId; } + + const headerParameters: runtime.HTTPHeaders = {}; + const response = await this.request({ path: `/developer-apps/{address}`.replace(`{${"address"}}`, encodeURIComponent(String(params.address))), method: 'DELETE', @@ -153,7 +238,7 @@ export class DeveloperAppsApi extends runtime.BaseAPI { } /** - * Deletes a developer app + * Deletes a developer app (Plans API). Indexer validates grants. */ async deleteDeveloperApp(params: DeleteDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { const response = await this.deleteDeveloperAppRaw(params, initOverrides); @@ -193,59 +278,45 @@ export class DeveloperAppsApi extends runtime.BaseAPI { /** * @hidden - * Updates an existing developer app + * Get developer apps for the user. */ - async updateDeveloperAppRaw(params: UpdateDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (params.address === null || params.address === undefined) { - throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling updateDeveloperApp.'); - } - - if (params.userId === null || params.userId === undefined) { - throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling updateDeveloperApp.'); - } - - if (params.metadata === null || params.metadata === undefined) { - throw new runtime.RequiredError('metadata','Required parameter params.metadata was null or undefined when calling updateDeveloperApp.'); + async getDeveloperAppsRaw(params: GetDeveloperAppsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.id === null || params.id === undefined) { + throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling getDeveloperApps.'); } const queryParameters: any = {}; - if (params.userId !== undefined) { - queryParameters['user_id'] = params.userId; + if (params.include !== undefined) { + queryParameters['include'] = params.include; } const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; - - if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) { - headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password); - } - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("BearerAuth", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } const response = await this.request({ - path: `/developer-apps/{address}`.replace(`{${"address"}}`, encodeURIComponent(String(params.address))), - method: 'PUT', + path: `/users/{id}/developer-apps`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))), + method: 'GET', headers: headerParameters, query: queryParameters, - body: UpdateDeveloperAppRequestBodyToJSON(params.metadata), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => WriteResponseFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => DeveloperAppsResponseFromJSON(jsonValue)); } /** - * Updates an existing developer app + * Get developer apps for the user. */ - async updateDeveloperApp(params: UpdateDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.updateDeveloperAppRaw(params, initOverrides); + async getDeveloperApps(params: GetDeveloperAppsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getDeveloperAppsRaw(params, initOverrides); return await response.value(); } } + +/** + * @export + */ +export const GetDeveloperAppsIncludeEnum = { + Metrics: 'metrics' +} as const; +export type GetDeveloperAppsIncludeEnum = typeof GetDeveloperAppsIncludeEnum[keyof typeof GetDeveloperAppsIncludeEnum]; diff --git a/packages/sdk/src/sdk/api/generated/default/apis/UsersApi.ts b/packages/sdk/src/sdk/api/generated/default/apis/UsersApi.ts index 3c7cb32c3ee..8eeb71bf43a 100644 --- a/packages/sdk/src/sdk/api/generated/default/apis/UsersApi.ts +++ b/packages/sdk/src/sdk/api/generated/default/apis/UsersApi.ts @@ -16,19 +16,16 @@ import * as runtime from '../runtime'; import type { + AddManagerRequestBody, AlbumsResponse, + ApproveGrantRequestBody, AuthorizedApps, BalanceHistoryResponse, CollectiblesResponse, ConnectedWalletsResponse, - CreateAccessKeyResponse, - CreateUserDeveloperAppRequestBody, - CreateUserDeveloperAppResponse, + CreateGrantRequestBody, CreateUserRequestBody, CreateUserResponse, - DeactivateAccessKeyRequestBody, - DeactivateAccessKeyResponse, - DeveloperAppsResponse, EmailAccessResponse, FavoritesResponse, FollowersResponse, @@ -63,8 +60,12 @@ import type { WriteResponse, } from '../models'; import { + AddManagerRequestBodyFromJSON, + AddManagerRequestBodyToJSON, AlbumsResponseFromJSON, AlbumsResponseToJSON, + ApproveGrantRequestBodyFromJSON, + ApproveGrantRequestBodyToJSON, AuthorizedAppsFromJSON, AuthorizedAppsToJSON, BalanceHistoryResponseFromJSON, @@ -73,22 +74,12 @@ import { CollectiblesResponseToJSON, ConnectedWalletsResponseFromJSON, ConnectedWalletsResponseToJSON, - CreateAccessKeyResponseFromJSON, - CreateAccessKeyResponseToJSON, - CreateUserDeveloperAppRequestBodyFromJSON, - CreateUserDeveloperAppRequestBodyToJSON, - CreateUserDeveloperAppResponseFromJSON, - CreateUserDeveloperAppResponseToJSON, + CreateGrantRequestBodyFromJSON, + CreateGrantRequestBodyToJSON, CreateUserRequestBodyFromJSON, CreateUserRequestBodyToJSON, CreateUserResponseFromJSON, CreateUserResponseToJSON, - DeactivateAccessKeyRequestBodyFromJSON, - DeactivateAccessKeyRequestBodyToJSON, - DeactivateAccessKeyResponseFromJSON, - DeactivateAccessKeyResponseToJSON, - DeveloperAppsResponseFromJSON, - DeveloperAppsResponseToJSON, EmailAccessResponseFromJSON, EmailAccessResponseToJSON, FavoritesResponseFromJSON, @@ -155,30 +146,24 @@ import { WriteResponseToJSON, } from '../models'; -export interface CreateUserRequest { - userId: string; - metadata: CreateUserRequestBody; -} - -export interface CreateUserDeveloperAppRequest { +export interface AddManagerRequest { id: string; - metadata: CreateUserDeveloperAppRequestBody; + addManagerRequestBody: AddManagerRequestBody; } -export interface CreateUserDeveloperAppAccessKeyRequest { +export interface ApproveGrantRequest { id: string; - address: string; + approveGrantRequestBody: ApproveGrantRequestBody; } -export interface DeactivateUserDeveloperAppAccessKeyRequest { +export interface CreateGrantRequest { id: string; - address: string; - metadata: DeactivateAccessKeyRequestBody; + createGrantRequestBody: CreateGrantRequestBody; } -export interface DeleteUserDeveloperAppRequest { - id: string; - address: string; +export interface CreateUserRequest { + userId: string; + metadata: CreateUserRequestBody; } export interface DownloadPurchasesAsCSVRequest { @@ -448,11 +433,6 @@ export interface GetUserCommentsRequest { userId?: string; } -export interface GetUserDeveloperAppsRequest { - id: string; - include?: GetUserDeveloperAppsIncludeEnum; -} - export interface GetUserEmailKeyRequest { receivingUserId: string; grantorUserId: string; @@ -500,6 +480,16 @@ export interface MuteUserRequest { userId: string; } +export interface RemoveManagerRequest { + id: string; + managerUserId: string; +} + +export interface RevokeGrantRequest { + id: string; + address: string; +} + export interface SearchUsersRequest { offset?: number; limit?: number; @@ -546,23 +536,19 @@ export class UsersApi extends runtime.BaseAPI { /** * @hidden - * Creates a new user + * Add a manager (authorize another user to act on your behalf) */ - async createUserRaw(params: CreateUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (params.userId === null || params.userId === undefined) { - throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling createUser.'); + async addManagerRaw(params: AddManagerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.id === null || params.id === undefined) { + throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling addManager.'); } - if (params.metadata === null || params.metadata === undefined) { - throw new runtime.RequiredError('metadata','Required parameter params.metadata was null or undefined when calling createUser.'); + if (params.addManagerRequestBody === null || params.addManagerRequestBody === undefined) { + throw new runtime.RequiredError('addManagerRequestBody','Required parameter params.addManagerRequestBody was null or undefined when calling addManager.'); } const queryParameters: any = {}; - if (params.userId !== undefined) { - queryParameters['user_id'] = params.userId; - } - const headerParameters: runtime.HTTPHeaders = {}; headerParameters['Content-Type'] = 'application/json'; @@ -579,35 +565,35 @@ export class UsersApi extends runtime.BaseAPI { } } const response = await this.request({ - path: `/users`, + path: `/users/{id}/managers`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))), method: 'POST', headers: headerParameters, query: queryParameters, - body: CreateUserRequestBodyToJSON(params.metadata), + body: AddManagerRequestBodyToJSON(params.addManagerRequestBody), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => CreateUserResponseFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => WriteResponseFromJSON(jsonValue)); } /** - * Creates a new user + * Add a manager (authorize another user to act on your behalf) */ - async createUser(params: CreateUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.createUserRaw(params, initOverrides); + async addManager(params: AddManagerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.addManagerRaw(params, initOverrides); return await response.value(); } /** * @hidden - * Create a new developer app (Plans API). Requires OAuth Bearer token with plans app grant. + * Approve a manager request (manager approves being added by the child user) */ - async createUserDeveloperAppRaw(params: CreateUserDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + async approveGrantRaw(params: ApproveGrantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { if (params.id === null || params.id === undefined) { - throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling createUserDeveloperApp.'); + throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling approveGrant.'); } - if (params.metadata === null || params.metadata === undefined) { - throw new runtime.RequiredError('metadata','Required parameter params.metadata was null or undefined when calling createUserDeveloperApp.'); + if (params.approveGrantRequestBody === null || params.approveGrantRequestBody === undefined) { + throw new runtime.RequiredError('approveGrantRequestBody','Required parameter params.approveGrantRequestBody was null or undefined when calling approveGrant.'); } const queryParameters: any = {}; @@ -628,41 +614,43 @@ export class UsersApi extends runtime.BaseAPI { } } const response = await this.request({ - path: `/users/{id}/developer-apps`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))), + path: `/users/{id}/grants/approve`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))), method: 'POST', headers: headerParameters, query: queryParameters, - body: CreateUserDeveloperAppRequestBodyToJSON(params.metadata), + body: ApproveGrantRequestBodyToJSON(params.approveGrantRequestBody), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => CreateUserDeveloperAppResponseFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => WriteResponseFromJSON(jsonValue)); } /** - * Create a new developer app (Plans API). Requires OAuth Bearer token with plans app grant. + * Approve a manager request (manager approves being added by the child user) */ - async createUserDeveloperApp(params: CreateUserDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.createUserDeveloperAppRaw(params, initOverrides); + async approveGrant(params: ApproveGrantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.approveGrantRaw(params, initOverrides); return await response.value(); } /** * @hidden - * Create a new bearer token (API access key) for a developer app (Plans API). Requires OAuth Bearer token with plans app grant. + * Create a grant (authorize an app to act on the user\'s behalf) */ - async createUserDeveloperAppAccessKeyRaw(params: CreateUserDeveloperAppAccessKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + async createGrantRaw(params: CreateGrantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { if (params.id === null || params.id === undefined) { - throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling createUserDeveloperAppAccessKey.'); + throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling createGrant.'); } - if (params.address === null || params.address === undefined) { - throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling createUserDeveloperAppAccessKey.'); + if (params.createGrantRequestBody === null || params.createGrantRequestBody === undefined) { + throw new runtime.RequiredError('createGrantRequestBody','Required parameter params.createGrantRequestBody was null or undefined when calling createGrant.'); } const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; + headerParameters['Content-Type'] = 'application/json'; + if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) { headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password); } @@ -675,42 +663,43 @@ export class UsersApi extends runtime.BaseAPI { } } const response = await this.request({ - path: `/users/{id}/developer-apps/{address}/access-keys`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))).replace(`{${"address"}}`, encodeURIComponent(String(params.address))), + path: `/users/{id}/grants`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))), method: 'POST', headers: headerParameters, query: queryParameters, + body: CreateGrantRequestBodyToJSON(params.createGrantRequestBody), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => CreateAccessKeyResponseFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => WriteResponseFromJSON(jsonValue)); } /** - * Create a new bearer token (API access key) for a developer app (Plans API). Requires OAuth Bearer token with plans app grant. + * Create a grant (authorize an app to act on the user\'s behalf) */ - async createUserDeveloperAppAccessKey(params: CreateUserDeveloperAppAccessKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.createUserDeveloperAppAccessKeyRaw(params, initOverrides); + async createGrant(params: CreateGrantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createGrantRaw(params, initOverrides); return await response.value(); } /** * @hidden - * Deactivate a bearer token (API access key) for a developer app (Plans API). Requires OAuth Bearer token with plans app grant. The deactivated token will no longer authenticate requests. + * Creates a new user */ - async deactivateUserDeveloperAppAccessKeyRaw(params: DeactivateUserDeveloperAppAccessKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (params.id === null || params.id === undefined) { - throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling deactivateUserDeveloperAppAccessKey.'); - } - - if (params.address === null || params.address === undefined) { - throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling deactivateUserDeveloperAppAccessKey.'); + async createUserRaw(params: CreateUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.userId === null || params.userId === undefined) { + throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling createUser.'); } if (params.metadata === null || params.metadata === undefined) { - throw new runtime.RequiredError('metadata','Required parameter params.metadata was null or undefined when calling deactivateUserDeveloperAppAccessKey.'); + throw new runtime.RequiredError('metadata','Required parameter params.metadata was null or undefined when calling createUser.'); } const queryParameters: any = {}; + if (params.userId !== undefined) { + queryParameters['user_id'] = params.userId; + } + const headerParameters: runtime.HTTPHeaders = {}; headerParameters['Content-Type'] = 'application/json'; @@ -727,67 +716,21 @@ export class UsersApi extends runtime.BaseAPI { } } const response = await this.request({ - path: `/users/{id}/developer-apps/{address}/access-keys/deactivate`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))).replace(`{${"address"}}`, encodeURIComponent(String(params.address))), + path: `/users`, method: 'POST', headers: headerParameters, query: queryParameters, - body: DeactivateAccessKeyRequestBodyToJSON(params.metadata), - }, initOverrides); - - return new runtime.JSONApiResponse(response, (jsonValue) => DeactivateAccessKeyResponseFromJSON(jsonValue)); - } - - /** - * Deactivate a bearer token (API access key) for a developer app (Plans API). Requires OAuth Bearer token with plans app grant. The deactivated token will no longer authenticate requests. - */ - async deactivateUserDeveloperAppAccessKey(params: DeactivateUserDeveloperAppAccessKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.deactivateUserDeveloperAppAccessKeyRaw(params, initOverrides); - return await response.value(); - } - - /** - * @hidden - * Delete a developer app (Plans API). Requires OAuth Bearer token with plans app grant. - */ - async deleteUserDeveloperAppRaw(params: DeleteUserDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (params.id === null || params.id === undefined) { - throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling deleteUserDeveloperApp.'); - } - - if (params.address === null || params.address === undefined) { - throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling deleteUserDeveloperApp.'); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) { - headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password); - } - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("BearerAuth", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request({ - path: `/users/{id}/developer-apps/{address}`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))).replace(`{${"address"}}`, encodeURIComponent(String(params.address))), - method: 'DELETE', - headers: headerParameters, - query: queryParameters, + body: CreateUserRequestBodyToJSON(params.metadata), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => WriteResponseFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => CreateUserResponseFromJSON(jsonValue)); } /** - * Delete a developer app (Plans API). Requires OAuth Bearer token with plans app grant. + * Creates a new user */ - async deleteUserDeveloperApp(params: DeleteUserDeveloperAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.deleteUserDeveloperAppRaw(params, initOverrides); + async createUser(params: CreateUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createUserRaw(params, initOverrides); return await response.value(); } @@ -2413,41 +2356,6 @@ export class UsersApi extends runtime.BaseAPI { return await response.value(); } - /** - * @hidden - * Get developer apps for the user (Plans API). Requires OAuth. - */ - async getUserDeveloperAppsRaw(params: GetUserDeveloperAppsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (params.id === null || params.id === undefined) { - throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling getUserDeveloperApps.'); - } - - const queryParameters: any = {}; - - if (params.include !== undefined) { - queryParameters['include'] = params.include; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request({ - path: `/users/{id}/developer-apps`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))), - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); - - return new runtime.JSONApiResponse(response, (jsonValue) => DeveloperAppsResponseFromJSON(jsonValue)); - } - - /** - * Get developer apps for the user (Plans API). Requires OAuth. - */ - async getUserDeveloperApps(params: GetUserDeveloperAppsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.getUserDeveloperAppsRaw(params, initOverrides); - return await response.value(); - } - /** * @hidden * Gets the encrypted key for email access between the receiving user and granting user. @@ -2768,6 +2676,98 @@ export class UsersApi extends runtime.BaseAPI { return await response.value(); } + /** + * @hidden + * Remove a manager (revoke user-to-user grant). Can be called by the child user or the manager. + */ + async removeManagerRaw(params: RemoveManagerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.id === null || params.id === undefined) { + throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling removeManager.'); + } + + if (params.managerUserId === null || params.managerUserId === undefined) { + throw new runtime.RequiredError('managerUserId','Required parameter params.managerUserId was null or undefined when calling removeManager.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) { + headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password); + } + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("BearerAuth", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/users/{id}/managers/{managerUserId}`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))).replace(`{${"managerUserId"}}`, encodeURIComponent(String(params.managerUserId))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => WriteResponseFromJSON(jsonValue)); + } + + /** + * Remove a manager (revoke user-to-user grant). Can be called by the child user or the manager. + */ + async removeManager(params: RemoveManagerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.removeManagerRaw(params, initOverrides); + return await response.value(); + } + + /** + * @hidden + * Revoke a grant (remove app authorization) + */ + async revokeGrantRaw(params: RevokeGrantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.id === null || params.id === undefined) { + throw new runtime.RequiredError('id','Required parameter params.id was null or undefined when calling revokeGrant.'); + } + + if (params.address === null || params.address === undefined) { + throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling revokeGrant.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) { + headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password); + } + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("BearerAuth", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/users/{id}/grants/{address}`.replace(`{${"id"}}`, encodeURIComponent(String(params.id))).replace(`{${"address"}}`, encodeURIComponent(String(params.address))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => WriteResponseFromJSON(jsonValue)); + } + + /** + * Revoke a grant (remove app authorization) + */ + async revokeGrant(params: RevokeGrantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.revokeGrantRaw(params, initOverrides); + return await response.value(); + } + /** * @hidden * Search for users that match the given query @@ -3278,13 +3278,6 @@ export const GetUserBalanceHistoryGranularityEnum = { Daily: 'daily' } as const; export type GetUserBalanceHistoryGranularityEnum = typeof GetUserBalanceHistoryGranularityEnum[keyof typeof GetUserBalanceHistoryGranularityEnum]; -/** - * @export - */ -export const GetUserDeveloperAppsIncludeEnum = { - Metrics: 'metrics' -} as const; -export type GetUserDeveloperAppsIncludeEnum = typeof GetUserDeveloperAppsIncludeEnum[keyof typeof GetUserDeveloperAppsIncludeEnum]; /** * @export */ diff --git a/packages/sdk/src/sdk/api/generated/default/models/AddManagerRequestBody.ts b/packages/sdk/src/sdk/api/generated/default/models/AddManagerRequestBody.ts new file mode 100644 index 00000000000..203822af092 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/default/models/AddManagerRequestBody.ts @@ -0,0 +1,67 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * Audius V1 API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AddManagerRequestBody + */ +export interface AddManagerRequestBody { + /** + * The user ID of the user to add as manager + * @type {string} + * @memberof AddManagerRequestBody + */ + managerUserId: string; +} + +/** + * Check if a given object implements the AddManagerRequestBody interface. + */ +export function instanceOfAddManagerRequestBody(value: object): value is AddManagerRequestBody { + let isInstance = true; + isInstance = isInstance && "managerUserId" in value && value["managerUserId"] !== undefined; + + return isInstance; +} + +export function AddManagerRequestBodyFromJSON(json: any): AddManagerRequestBody { + return AddManagerRequestBodyFromJSONTyped(json, false); +} + +export function AddManagerRequestBodyFromJSONTyped(json: any, ignoreDiscriminator: boolean): AddManagerRequestBody { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'managerUserId': json['manager_user_id'], + }; +} + +export function AddManagerRequestBodyToJSON(value?: AddManagerRequestBody | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'manager_user_id': value.managerUserId, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/default/models/ApproveGrantRequestBody.ts b/packages/sdk/src/sdk/api/generated/default/models/ApproveGrantRequestBody.ts new file mode 100644 index 00000000000..5e67bd3ade6 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/default/models/ApproveGrantRequestBody.ts @@ -0,0 +1,67 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * Audius V1 API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ApproveGrantRequestBody + */ +export interface ApproveGrantRequestBody { + /** + * The user ID of the child user who proposed the manager (grantor) + * @type {string} + * @memberof ApproveGrantRequestBody + */ + grantorUserId: string; +} + +/** + * Check if a given object implements the ApproveGrantRequestBody interface. + */ +export function instanceOfApproveGrantRequestBody(value: object): value is ApproveGrantRequestBody { + let isInstance = true; + isInstance = isInstance && "grantorUserId" in value && value["grantorUserId"] !== undefined; + + return isInstance; +} + +export function ApproveGrantRequestBodyFromJSON(json: any): ApproveGrantRequestBody { + return ApproveGrantRequestBodyFromJSONTyped(json, false); +} + +export function ApproveGrantRequestBodyFromJSONTyped(json: any, ignoreDiscriminator: boolean): ApproveGrantRequestBody { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'grantorUserId': json['grantor_user_id'], + }; +} + +export function ApproveGrantRequestBodyToJSON(value?: ApproveGrantRequestBody | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'grantor_user_id': value.grantorUserId, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppRequestBody.ts b/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppRequestBody.ts index f0140ca917f..404d87c473c 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppRequestBody.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppRequestBody.ts @@ -14,13 +14,6 @@ */ import { exists, mapValues } from '../runtime'; -import type { CreateDeveloperAppRequestBodyAppSignature } from './CreateDeveloperAppRequestBodyAppSignature'; -import { - CreateDeveloperAppRequestBodyAppSignatureFromJSON, - CreateDeveloperAppRequestBodyAppSignatureFromJSONTyped, - CreateDeveloperAppRequestBodyAppSignatureToJSON, -} from './CreateDeveloperAppRequestBodyAppSignature'; - /** * * @export @@ -38,19 +31,13 @@ export interface CreateDeveloperAppRequestBody { * @type {string} * @memberof CreateDeveloperAppRequestBody */ - description: string; + description?: string; /** - * App logo/image URL (camelCase) + * App logo/image URL * @type {string} * @memberof CreateDeveloperAppRequestBody */ - imageUrl: string; - /** - * - * @type {CreateDeveloperAppRequestBodyAppSignature} - * @memberof CreateDeveloperAppRequestBody - */ - appSignature: CreateDeveloperAppRequestBodyAppSignature; + imageUrl?: string; } /** @@ -59,9 +46,6 @@ export interface CreateDeveloperAppRequestBody { export function instanceOfCreateDeveloperAppRequestBody(value: object): value is CreateDeveloperAppRequestBody { let isInstance = true; isInstance = isInstance && "name" in value && value["name"] !== undefined; - isInstance = isInstance && "description" in value && value["description"] !== undefined; - isInstance = isInstance && "imageUrl" in value && value["imageUrl"] !== undefined; - isInstance = isInstance && "appSignature" in value && value["appSignature"] !== undefined; return isInstance; } @@ -77,9 +61,8 @@ export function CreateDeveloperAppRequestBodyFromJSONTyped(json: any, ignoreDisc return { 'name': json['name'], - 'description': json['description'], - 'imageUrl': json['imageUrl'], - 'appSignature': CreateDeveloperAppRequestBodyAppSignatureFromJSON(json['appSignature']), + 'description': !exists(json, 'description') ? undefined : json['description'], + 'imageUrl': !exists(json, 'imageUrl') ? undefined : json['imageUrl'], }; } @@ -95,7 +78,6 @@ export function CreateDeveloperAppRequestBodyToJSON(value?: CreateDeveloperAppRe 'name': value.name, 'description': value.description, 'imageUrl': value.imageUrl, - 'appSignature': CreateDeveloperAppRequestBodyAppSignatureToJSON(value.appSignature), }; } diff --git a/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppRequestBodyAppSignature.ts b/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppRequestBodyAppSignature.ts deleted file mode 100644 index 9d515049580..00000000000 --- a/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppRequestBodyAppSignature.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -// @ts-nocheck -/** - * API - * Audius V1 API - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from '../runtime'; -/** - * - * @export - * @interface CreateDeveloperAppRequestBodyAppSignature - */ -export interface CreateDeveloperAppRequestBodyAppSignature { - /** - * Signed message - * @type {string} - * @memberof CreateDeveloperAppRequestBodyAppSignature - */ - message: string; - /** - * Signature - * @type {string} - * @memberof CreateDeveloperAppRequestBodyAppSignature - */ - signature: string; -} - -/** - * Check if a given object implements the CreateDeveloperAppRequestBodyAppSignature interface. - */ -export function instanceOfCreateDeveloperAppRequestBodyAppSignature(value: object): value is CreateDeveloperAppRequestBodyAppSignature { - let isInstance = true; - isInstance = isInstance && "message" in value && value["message"] !== undefined; - isInstance = isInstance && "signature" in value && value["signature"] !== undefined; - - return isInstance; -} - -export function CreateDeveloperAppRequestBodyAppSignatureFromJSON(json: any): CreateDeveloperAppRequestBodyAppSignature { - return CreateDeveloperAppRequestBodyAppSignatureFromJSONTyped(json, false); -} - -export function CreateDeveloperAppRequestBodyAppSignatureFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateDeveloperAppRequestBodyAppSignature { - if ((json === undefined) || (json === null)) { - return json; - } - return { - - 'message': json['message'], - 'signature': json['signature'], - }; -} - -export function CreateDeveloperAppRequestBodyAppSignatureToJSON(value?: CreateDeveloperAppRequestBodyAppSignature | null): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - - 'message': value.message, - 'signature': value.signature, - }; -} - diff --git a/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppResponse.ts b/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppResponse.ts new file mode 100644 index 00000000000..f9e25a2e9bb --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/default/models/CreateDeveloperAppResponse.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * Audius V1 API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateDeveloperAppResponse + */ +export interface CreateDeveloperAppResponse { + /** + * The API key (address) for the developer app + * @type {string} + * @memberof CreateDeveloperAppResponse + */ + apiKey?: string; + /** + * The private key for the developer app (for signing) + * @type {string} + * @memberof CreateDeveloperAppResponse + */ + apiSecret?: string; + /** + * The bearer token for API authentication (use in Authorization header) + * @type {string} + * @memberof CreateDeveloperAppResponse + */ + bearerToken?: string; + /** + * Transaction hash of the creation + * @type {string} + * @memberof CreateDeveloperAppResponse + */ + transactionHash?: string; +} + +/** + * Check if a given object implements the CreateDeveloperAppResponse interface. + */ +export function instanceOfCreateDeveloperAppResponse(value: object): value is CreateDeveloperAppResponse { + let isInstance = true; + + return isInstance; +} + +export function CreateDeveloperAppResponseFromJSON(json: any): CreateDeveloperAppResponse { + return CreateDeveloperAppResponseFromJSONTyped(json, false); +} + +export function CreateDeveloperAppResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateDeveloperAppResponse { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'apiKey': !exists(json, 'api_key') ? undefined : json['api_key'], + 'apiSecret': !exists(json, 'api_secret') ? undefined : json['api_secret'], + 'bearerToken': !exists(json, 'bearer_token') ? undefined : json['bearer_token'], + 'transactionHash': !exists(json, 'transaction_hash') ? undefined : json['transaction_hash'], + }; +} + +export function CreateDeveloperAppResponseToJSON(value?: CreateDeveloperAppResponse | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'api_key': value.apiKey, + 'api_secret': value.apiSecret, + 'bearer_token': value.bearerToken, + 'transaction_hash': value.transactionHash, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/default/models/CreateGrantRequestBody.ts b/packages/sdk/src/sdk/api/generated/default/models/CreateGrantRequestBody.ts new file mode 100644 index 00000000000..8921acfa70a --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/default/models/CreateGrantRequestBody.ts @@ -0,0 +1,67 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * Audius V1 API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateGrantRequestBody + */ +export interface CreateGrantRequestBody { + /** + * The developer app address (API key) to grant authorization to + * @type {string} + * @memberof CreateGrantRequestBody + */ + appApiKey: string; +} + +/** + * Check if a given object implements the CreateGrantRequestBody interface. + */ +export function instanceOfCreateGrantRequestBody(value: object): value is CreateGrantRequestBody { + let isInstance = true; + isInstance = isInstance && "appApiKey" in value && value["appApiKey"] !== undefined; + + return isInstance; +} + +export function CreateGrantRequestBodyFromJSON(json: any): CreateGrantRequestBody { + return CreateGrantRequestBodyFromJSONTyped(json, false); +} + +export function CreateGrantRequestBodyFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateGrantRequestBody { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'appApiKey': json['app_api_key'], + }; +} + +export function CreateGrantRequestBodyToJSON(value?: CreateGrantRequestBody | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'app_api_key': value.appApiKey, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/default/models/CreateUserDeveloperAppResponse.ts b/packages/sdk/src/sdk/api/generated/default/models/CreateUserDeveloperAppResponse.ts index b7ad26eed83..c4b6427309c 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/CreateUserDeveloperAppResponse.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/CreateUserDeveloperAppResponse.ts @@ -27,11 +27,17 @@ export interface CreateUserDeveloperAppResponse { */ apiKey?: string; /** - * The API secret (access key) for the developer app + * The private key for the developer app (for signing) * @type {string} * @memberof CreateUserDeveloperAppResponse */ apiSecret?: string; + /** + * The bearer token for API authentication (use in Authorization header) + * @type {string} + * @memberof CreateUserDeveloperAppResponse + */ + bearerToken?: string; /** * Transaction hash of the creation * @type {string} @@ -61,6 +67,7 @@ export function CreateUserDeveloperAppResponseFromJSONTyped(json: any, ignoreDis 'apiKey': !exists(json, 'api_key') ? undefined : json['api_key'], 'apiSecret': !exists(json, 'api_secret') ? undefined : json['api_secret'], + 'bearerToken': !exists(json, 'bearer_token') ? undefined : json['bearer_token'], 'transactionHash': !exists(json, 'transaction_hash') ? undefined : json['transaction_hash'], }; } @@ -76,6 +83,7 @@ export function CreateUserDeveloperAppResponseToJSON(value?: CreateUserDeveloper 'api_key': value.apiKey, 'api_secret': value.apiSecret, + 'bearer_token': value.bearerToken, 'transaction_hash': value.transactionHash, }; } diff --git a/packages/sdk/src/sdk/api/generated/default/models/PinCommentRequestBody.ts b/packages/sdk/src/sdk/api/generated/default/models/PinCommentRequestBody.ts index 75e2154e034..27171bf5c0b 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/PinCommentRequestBody.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/PinCommentRequestBody.ts @@ -14,12 +14,25 @@ */ import { exists, mapValues } from '../runtime'; +import type { CommentEntityType } from './CommentEntityType'; +import { + CommentEntityTypeFromJSON, + CommentEntityTypeFromJSONTyped, + CommentEntityTypeToJSON, +} from './CommentEntityType'; + /** * * @export * @interface PinCommentRequestBody */ export interface PinCommentRequestBody { + /** + * + * @type {CommentEntityType} + * @memberof PinCommentRequestBody + */ + entityType: CommentEntityType; /** * ID of the entity (track or playlist) the comment is on * @type {number} @@ -33,6 +46,7 @@ export interface PinCommentRequestBody { */ export function instanceOfPinCommentRequestBody(value: object): value is PinCommentRequestBody { let isInstance = true; + isInstance = isInstance && "entityType" in value && value["entityType"] !== undefined; isInstance = isInstance && "entityId" in value && value["entityId"] !== undefined; return isInstance; @@ -48,6 +62,7 @@ export function PinCommentRequestBodyFromJSONTyped(json: any, ignoreDiscriminato } return { + 'entityType': CommentEntityTypeFromJSON(json['entityType']), 'entityId': json['entityId'], }; } @@ -61,6 +76,7 @@ export function PinCommentRequestBodyToJSON(value?: PinCommentRequestBody | null } return { + 'entityType': CommentEntityTypeToJSON(value.entityType), 'entityId': value.entityId, }; } diff --git a/packages/sdk/src/sdk/api/generated/default/models/UpdateDeveloperAppRequestBody.ts b/packages/sdk/src/sdk/api/generated/default/models/UpdateDeveloperAppRequestBody.ts index 774dc468da7..a3bcbe4f3ac 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/UpdateDeveloperAppRequestBody.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/UpdateDeveloperAppRequestBody.ts @@ -31,13 +31,13 @@ export interface UpdateDeveloperAppRequestBody { * @type {string} * @memberof UpdateDeveloperAppRequestBody */ - description: string; + description?: string; /** * App logo/image URL (camelCase) * @type {string} * @memberof UpdateDeveloperAppRequestBody */ - imageUrl: string; + imageUrl?: string; } /** @@ -46,8 +46,6 @@ export interface UpdateDeveloperAppRequestBody { export function instanceOfUpdateDeveloperAppRequestBody(value: object): value is UpdateDeveloperAppRequestBody { let isInstance = true; isInstance = isInstance && "name" in value && value["name"] !== undefined; - isInstance = isInstance && "description" in value && value["description"] !== undefined; - isInstance = isInstance && "imageUrl" in value && value["imageUrl"] !== undefined; return isInstance; } @@ -63,8 +61,8 @@ export function UpdateDeveloperAppRequestBodyFromJSONTyped(json: any, ignoreDisc return { 'name': json['name'], - 'description': json['description'], - 'imageUrl': json['imageUrl'], + 'description': !exists(json, 'description') ? undefined : json['description'], + 'imageUrl': !exists(json, 'imageUrl') ? undefined : json['imageUrl'], }; } diff --git a/packages/sdk/src/sdk/api/generated/default/models/index.ts b/packages/sdk/src/sdk/api/generated/default/models/index.ts index 791c42ad9fd..fb732a8146c 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/index.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/index.ts @@ -4,8 +4,10 @@ export * from './Access'; export * from './AccessGate'; export * from './AccessInfoResponse'; export * from './Activity'; +export * from './AddManagerRequestBody'; export * from './AlbumBacklink'; export * from './AlbumsResponse'; +export * from './ApproveGrantRequestBody'; export * from './AuthorizedApp'; export * from './AuthorizedApps'; export * from './BalanceHistoryDataPoint'; @@ -53,7 +55,8 @@ export * from './CreateCoinResponseData'; export * from './CreateCommentRequestBody'; export * from './CreateCommentResponse'; export * from './CreateDeveloperAppRequestBody'; -export * from './CreateDeveloperAppRequestBodyAppSignature'; +export * from './CreateDeveloperAppResponse'; +export * from './CreateGrantRequestBody'; export * from './CreatePlaylistRequestBody'; export * from './CreatePlaylistResponse'; export * from './CreateRewardCodeRequestBody'; diff --git a/packages/sdk/src/sdk/api/grants/GrantsApi.ts b/packages/sdk/src/sdk/api/grants/GrantsApi.ts index b40563fb798..82f6cead779 100644 --- a/packages/sdk/src/sdk/api/grants/GrantsApi.ts +++ b/packages/sdk/src/sdk/api/grants/GrantsApi.ts @@ -1,19 +1,24 @@ -import type { UsersApi, Configuration, User } from '../../api/generated/default' +import type { Configuration, User, UsersApi } from '../../api/generated/default' import type { EntityManagerService } from '../../services' -import { Action, EntityType } from '../../services/EntityManager/types' +import { + Action, + AdvancedOptions, + EntityType +} from '../../services/EntityManager/types' import { encodeHashId } from '../../utils/hashId' import { parseParams } from '../../utils/parseParams' import { ApproveGrantSchema, - ApproveGrantRequest, - AddManagerRequest, + type ApproveGrantRequest, AddManagerSchema, - CreateGrantRequest, + type AddManagerRequest, + type CreateGrantRequest, CreateGrantSchema, - RevokeGrantRequest, - RevokeGrantSchema, - RemoveManagerRequest + type RemoveManagerRequest, + RemoveManagerSchema, + type RevokeGrantRequest, + RevokeGrantSchema } from './types' export class GrantsApi { @@ -24,11 +29,10 @@ export class GrantsApi { private readonly usersApi: UsersApi ) {} - /** - * When user authorizes app to perform actions on their behalf. - * For user-to-user grants, use `addManager`. - */ - async createGrant(params: CreateGrantRequest) { + async createGrantWithEntityManager( + params: CreateGrantRequest, + advancedOptions?: AdvancedOptions + ) { const { userId, appApiKey } = await parseParams( 'createGrant', CreateGrantSchema @@ -37,89 +41,119 @@ export class GrantsApi { return await this.entityManager.manageEntity({ userId, entityType: EntityType.GRANT, - entityId: 0, // Contract requires uint, but we don't actually need this field for this action. Just use 0. + entityId: 0, action: Action.CREATE, metadata: JSON.stringify({ grantee_address: `0x${appApiKey}` - }) + }), + ...advancedOptions }) } - /** - * When user authorizes another user to perform actions on their behalf. - * The grant has to be approved by the proposed manager. - */ - async addManager(params: AddManagerRequest) { + async createGrant(params: CreateGrantRequest, requestInit?: RequestInit) { + if (this.entityManager) { + return await this.createGrantWithEntityManager(params) + } + const { userId, appApiKey } = await parseParams( + 'createGrant', + CreateGrantSchema + )(params) + return await this.usersApi.createGrant( + { + id: encodeHashId(userId)!, + createGrantRequestBody: { appApiKey } + }, + requestInit + ) + } + + async addManagerWithEntityManager( + params: AddManagerRequest, + advancedOptions?: AdvancedOptions + ) { const { userId, managerUserId } = await parseParams( 'addManager', AddManagerSchema )(params) - let managerUser: User | undefined - try { - managerUser = ( - await this.usersApi.getUser({ - id: encodeHashId(managerUserId)! - }) - ).data - if (!managerUser) { - throw new Error() - } - } catch (e) { - throw new Error( - '`managerUserId` passed to `addManager` method is invalid.' - ) - } + const managerUser = await this.getManagerUser(managerUserId, 'addManager') return await this.entityManager.manageEntity({ userId, entityType: EntityType.GRANT, - entityId: 0, // Contract requires uint, but we don't actually need this field for this action. Just use 0. + entityId: 0, action: Action.CREATE, metadata: JSON.stringify({ - grantee_address: managerUser!.ercWallet - }) + grantee_address: managerUser.ercWallet + }), + ...advancedOptions }) } - /** - * Revokes a user's manager access - can either be called by the manager user or the child user - */ - async removeManager(params: RemoveManagerRequest) { + async addManager(params: AddManagerRequest, requestInit?: RequestInit) { + if (this.entityManager) { + return await this.addManagerWithEntityManager(params) + } const { userId, managerUserId } = await parseParams( 'addManager', AddManagerSchema )(params) - let managerUser: User | undefined - try { - managerUser = ( - await this.usersApi.getUser({ - id: encodeHashId(managerUserId)! - }) - ).data - if (!managerUser) { - throw new Error() - } - } catch (e) { - throw new Error( - '`managerUserId` passed to `removeManager` method is invalid.' - ) - } + return await this.usersApi.addManager( + { + id: encodeHashId(userId)!, + addManagerRequestBody: { + managerUserId: encodeHashId(managerUserId)! + } + }, + requestInit + ) + } + + async removeManagerWithEntityManager( + params: RemoveManagerRequest, + advancedOptions?: AdvancedOptions + ) { + const { userId, managerUserId } = await parseParams( + 'removeManager', + RemoveManagerSchema + )(params) + const managerUser = await this.getManagerUser( + managerUserId, + 'removeManager' + ) return await this.entityManager.manageEntity({ userId, entityType: EntityType.GRANT, - entityId: 0, // Contract requires uint, but we don't actually need this field for this action. Just use 0. + entityId: 0, action: Action.DELETE, metadata: JSON.stringify({ - grantee_address: managerUser!.ercWallet - }) + grantee_address: managerUser.ercWallet + }), + ...advancedOptions }) } - /** - * When user revokes an app's authorization to perform actions on their behalf - */ - async revokeGrant(params: RevokeGrantRequest) { + async removeManager(params: RemoveManagerRequest, requestInit?: RequestInit) { + if (this.entityManager) { + return await this.removeManagerWithEntityManager(params) + } + const { userId, managerUserId } = await parseParams( + 'removeManager', + RemoveManagerSchema + )(params) + return await this.usersApi.removeManager( + { + id: encodeHashId(userId)!, + managerUserId: encodeHashId(managerUserId)! + }, + requestInit + ) + } + + async revokeGrantWithEntityManager( + params: RevokeGrantRequest, + advancedOptions?: AdvancedOptions + ) { const { userId, appApiKey } = await parseParams( 'revokeGrant', RevokeGrantSchema @@ -128,18 +162,36 @@ export class GrantsApi { return await this.entityManager.manageEntity({ userId, entityType: EntityType.GRANT, - entityId: 0, // Contract requires uint, but we don't actually need this field for this action. Just use 0. + entityId: 0, action: Action.DELETE, metadata: JSON.stringify({ grantee_address: `0x${appApiKey}` - }) + }), + ...advancedOptions }) } - /** - * Approve manager request - */ - async approveGrant(params: ApproveGrantRequest) { + async revokeGrant(params: RevokeGrantRequest, requestInit?: RequestInit) { + if (this.entityManager) { + return await this.revokeGrantWithEntityManager(params) + } + const { userId, appApiKey } = await parseParams( + 'revokeGrant', + RevokeGrantSchema + )(params) + return await this.usersApi.revokeGrant( + { + id: encodeHashId(userId)!, + address: appApiKey + }, + requestInit + ) + } + + async approveGrantWithEntityManager( + params: ApproveGrantRequest, + advancedOptions?: AdvancedOptions + ) { const { userId, grantorUserId } = await parseParams( 'approveGrant', ApproveGrantSchema @@ -152,7 +204,44 @@ export class GrantsApi { action: Action.APPROVE, metadata: JSON.stringify({ grantor_user_id: grantorUserId - }) + }), + ...advancedOptions }) } + + async approveGrant(params: ApproveGrantRequest, requestInit?: RequestInit) { + if (this.entityManager) { + return await this.approveGrantWithEntityManager(params) + } + const { userId, grantorUserId } = await parseParams( + 'approveGrant', + ApproveGrantSchema + )(params) + return await this.usersApi.approveGrant( + { + id: encodeHashId(userId)!, + approveGrantRequestBody: { + grantorUserId: encodeHashId(grantorUserId)! + } + }, + requestInit + ) + } + + private async getManagerUser( + managerUserId: number, + operation: string + ): Promise { + const managerUser = ( + await this.usersApi.getUser({ + id: encodeHashId(managerUserId)! + }) + ).data + if (!managerUser?.ercWallet) { + throw new Error( + `\`managerUserId\` passed to \`${operation}\` method is invalid.` + ) + } + return managerUser + } } diff --git a/packages/web/src/pages/settings-page/components/desktop/DeveloperApps/AppDetailsPage.tsx b/packages/web/src/pages/settings-page/components/desktop/DeveloperApps/AppDetailsPage.tsx index feb2c2e43fe..28ebd14d517 100644 --- a/packages/web/src/pages/settings-page/components/desktop/DeveloperApps/AppDetailsPage.tsx +++ b/packages/web/src/pages/settings-page/components/desktop/DeveloperApps/AppDetailsPage.tsx @@ -22,12 +22,14 @@ const AUDIUS_SDK_LINK = 'https://docs.audius.org/developers' const messages = { secretReminder: - "Remember to save your API Secret. You won't be able to view it again.", + "Remember to save your API Secret and Bearer Token. You won't be able to view them again.", description: 'Description', apiKey: 'api key', copyApiKeyLabel: 'copy api key', apiSecret: 'api secret', copyApiSecretLabel: 'copy api secret', + bearerToken: 'bearer token', + copyBearerTokenLabel: 'copy bearer token', copied: 'Copied!', readTheDocs: 'Read the Developer Docs', goBack: 'Back to Your Apps' @@ -40,7 +42,7 @@ export const AppDetailsPage = (props: AppDetailsPageProps) => { setPage(CreateAppsPages.YOUR_APPS) }, [setPage]) - const { name, description, apiKey, apiSecret } = params || {} + const { name, description, apiKey, apiSecret, bearerToken } = params ?? {} const copyApiKey = useCallback(() => { if (!apiKey) return copyToClipboard(apiKey) @@ -51,11 +53,16 @@ export const AppDetailsPage = (props: AppDetailsPageProps) => { copyToClipboard(apiSecret) }, [apiSecret]) + const copyBearerToken = useCallback(() => { + if (!bearerToken) return + copyToClipboard(bearerToken) + }, [bearerToken]) + if (!params) return null return (
- {!apiSecret ? null : ( + {!apiSecret && !bearerToken ? null : ( { > + + +
+ )} + {!bearerToken ? null : ( +
+ {messages.bearerToken} + + {bearerToken} + + + +