diff --git a/db/migrations/1709038872576-Views.js b/db/migrations/1709038872576-Views.js index 36bf38fad..16b6b0264 100644 --- a/db/migrations/1709038872576-Views.js +++ b/db/migrations/1709038872576-Views.js @@ -1,4 +1,3 @@ - const { getViewDefinitions } = require('../viewDefinitions') module.exports = class Views1709038872576 { diff --git a/schema/auth.graphql b/schema/auth.graphql index 0f2d58461..b02b7ee7d 100644 --- a/schema/auth.graphql +++ b/schema/auth.graphql @@ -12,6 +12,7 @@ enum OperatorPermission { EXCLUDE_CONTENT RESTORE_CONTENT SET_PUBLIC_FEED_VIDEOS + SET_FEATURED_CRTS } type User @entity @schema(name: "admin") { diff --git a/schema/token.graphql b/schema/token.graphql index 63ed68826..e33cd1d22 100644 --- a/schema/token.graphql +++ b/schema/token.graphql @@ -29,6 +29,9 @@ type CreatorToken @entity { "total supply" totalSupply: BigInt! + "Flag to indicate whether the CRT is featured or not" + isFeatured: Boolean! + "sales issued for this token" sales: [Sale!] @derivedFrom(field: "token") @@ -51,7 +54,7 @@ type CreatorToken @entity { ammCurves: [AmmCurve!] @derivedFrom(field: "token") "date at which this token was created" - createdAt: DateTime! + createdAt: DateTime! @index "channel from which the token is issued uniqueness guaranteed by runtime" channel: TokenChannel @derivedFrom(field: "token") diff --git a/src/auth-server/docs/.openapi-generator/FILES b/src/auth-server/docs/.openapi-generator/FILES index 6ac6b8e33..33a91b3b2 100644 --- a/src/auth-server/docs/.openapi-generator/FILES +++ b/src/auth-server/docs/.openapi-generator/FILES @@ -4,12 +4,11 @@ Models/ActionExecutionRequestData.md Models/AnonymousUserAuthRequestData.md Models/AnonymousUserAuthResponseData.md Models/AnonymousUserAuthResponseData_allOf.md +Models/ChangeAccountRequestData.md +Models/ChangeAccountRequestData_allOf.md Models/ConfirmEmailRequestData.md -Models/ConnectAccountRequestData.md -Models/ConnectAccountRequestData_allOf.md Models/CreateAccountRequestData.md Models/CreateAccountRequestData_allOf.md -Models/DisconnectAccountRequestData.md Models/EncryptionArtifacts.md Models/GenericErrorResponseData.md Models/GenericOkResponseData.md diff --git a/src/auth-server/docs/Apis/DefaultApi.md b/src/auth-server/docs/Apis/DefaultApi.md index 41b09c586..6a4fabc21 100644 --- a/src/auth-server/docs/Apis/DefaultApi.md +++ b/src/auth-server/docs/Apis/DefaultApi.md @@ -1,20 +1,17 @@ # DefaultApi -All URIs are relative to *http://localhost:4074/api/v1* +All URIs are relative to *http://localhost/api/v1* | Method | HTTP request | Description | |------------- | ------------- | -------------| | [**anonymousAuth**](DefaultApi.md#anonymousAuth) | **POST** /anonymous-auth | | +| [**changeAccount**](DefaultApi.md#changeAccount) | **POST** /change-account | | | [**confirmEmail**](DefaultApi.md#confirmEmail) | **POST** /confirm-email | | -| [**connectAccount**](DefaultApi.md#connectAccount) | **POST** /connect-account | | | [**createAccount**](DefaultApi.md#createAccount) | **POST** /account | | -| [**deleteArtifacts**](DefaultApi.md#deleteArtifacts) | **DELETE** /artifacts | | -| [**disconnectAccount**](DefaultApi.md#disconnectAccount) | **POST** /disconnect-account | | | [**getArtifacts**](DefaultApi.md#getArtifacts) | **GET** /artifacts | | | [**getSessionArtifacts**](DefaultApi.md#getSessionArtifacts) | **GET** /session-artifacts | | | [**login**](DefaultApi.md#login) | **POST** /login | | | [**logout**](DefaultApi.md#logout) | **POST** /logout | | -| [**postArtifacts**](DefaultApi.md#postArtifacts) | **POST** /artifacts | | | [**postSessionArtifacts**](DefaultApi.md#postSessionArtifacts) | **POST** /session-artifacts | | | [**requestEmailConfirmationToken**](DefaultApi.md#requestEmailConfirmationToken) | **POST** /request-email-confirmation-token | | @@ -46,19 +43,19 @@ No authorization required - **Content-Type**: application/json - **Accept**: application/json - -# **confirmEmail** -> GenericOkResponseData confirmEmail(ConfirmEmailRequestData) + +# **changeAccount** +> GenericOkResponseData changeAccount(ChangeAccountRequestData) - Confirm account's e-mail address provided during registration. + Change the blockchain (Joystream) account associated with the Gateway account. Delete the old account's encryption artifacts and optionally set new ones. ### Parameters |Name | Type | Description | Notes | |------------- | ------------- | ------------- | -------------| -| **ConfirmEmailRequestData** | [**ConfirmEmailRequestData**](../Models/ConfirmEmailRequestData.md)| | [optional] | +| **ChangeAccountRequestData** | [**ChangeAccountRequestData**](../Models/ChangeAccountRequestData.md)| | [optional] | ### Return type @@ -66,26 +63,26 @@ No authorization required ### Authorization -No authorization required +[cookieAuth](../README.md#cookieAuth) ### HTTP request headers - **Content-Type**: application/json - **Accept**: application/json - -# **connectAccount** -> GenericOkResponseData connectAccount(ConnectAccountRequestData) + +# **confirmEmail** +> GenericOkResponseData confirmEmail(ConfirmEmailRequestData) - Connect a Joystream account (key) with the Gateway acount by providing a signed proof of ownership. + Confirm account's e-mail address provided during registration. ### Parameters |Name | Type | Description | Notes | |------------- | ------------- | ------------- | -------------| -| **ConnectAccountRequestData** | [**ConnectAccountRequestData**](../Models/ConnectAccountRequestData.md)| | [optional] | +| **ConfirmEmailRequestData** | [**ConfirmEmailRequestData**](../Models/ConfirmEmailRequestData.md)| | [optional] | ### Return type @@ -93,7 +90,7 @@ No authorization required ### Authorization -[cookieAuth](../README.md#cookieAuth) +No authorization required ### HTTP request headers @@ -127,57 +124,6 @@ No authorization required - **Content-Type**: application/json - **Accept**: application/json - -# **deleteArtifacts** -> GenericOkResponseData deleteArtifacts() - - - - Delete wallet seed encryption artifacts in case they are no longer needed. - -### Parameters -This endpoint does not need any parameter. - -### Return type - -[**GenericOkResponseData**](../Models/GenericOkResponseData.md) - -### Authorization - -[cookieAuth](../README.md#cookieAuth) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: application/json - - -# **disconnectAccount** -> GenericOkResponseData disconnectAccount(DisconnectAccountRequestData) - - - - Disconnect a Joystream account (key) from the Gateway acount. - -### Parameters - -|Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **DisconnectAccountRequestData** | [**DisconnectAccountRequestData**](../Models/DisconnectAccountRequestData.md)| | [optional] | - -### Return type - -[**GenericOkResponseData**](../Models/GenericOkResponseData.md) - -### Authorization - -[cookieAuth](../README.md#cookieAuth) - -### HTTP request headers - -- **Content-Type**: application/json -- **Accept**: application/json - # **getArtifacts** > EncryptionArtifacts getArtifacts(id, email) @@ -236,7 +182,7 @@ This endpoint does not need any parameter. - Login to user's account by providing a message signed by one of the user's connected accounts. + Login to user's account by providing a message signed by the associated blockchain account. ### Parameters @@ -281,33 +227,6 @@ This endpoint does not need any parameter. - **Content-Type**: Not defined - **Accept**: application/json - -# **postArtifacts** -> GenericOkResponseData postArtifacts(EncryptionArtifacts) - - - - Save wallet seed encryption artifacts associated with the account (if not already saved). - -### Parameters - -|Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **EncryptionArtifacts** | [**EncryptionArtifacts**](../Models/EncryptionArtifacts.md)| | [optional] | - -### Return type - -[**GenericOkResponseData**](../Models/GenericOkResponseData.md) - -### Authorization - -[cookieAuth](../README.md#cookieAuth) - -### HTTP request headers - -- **Content-Type**: application/json -- **Accept**: application/json - # **postSessionArtifacts** > GenericOkResponseData postSessionArtifacts(SessionEncryptionArtifacts) diff --git a/src/auth-server/docs/Models/ConnectAccountRequestData.md b/src/auth-server/docs/Models/ChangeAccountRequestData.md similarity index 93% rename from src/auth-server/docs/Models/ConnectAccountRequestData.md rename to src/auth-server/docs/Models/ChangeAccountRequestData.md index 2d48c48c2..ca515f5c4 100644 --- a/src/auth-server/docs/Models/ConnectAccountRequestData.md +++ b/src/auth-server/docs/Models/ChangeAccountRequestData.md @@ -1,4 +1,4 @@ -# ConnectAccountRequestData +# ChangeAccountRequestData ## Properties | Name | Type | Description | Notes | diff --git a/src/auth-server/docs/Models/ConnectAccountRequestData_allOf.md b/src/auth-server/docs/Models/ChangeAccountRequestData_allOf.md similarity index 91% rename from src/auth-server/docs/Models/ConnectAccountRequestData_allOf.md rename to src/auth-server/docs/Models/ChangeAccountRequestData_allOf.md index b8775df4e..edad4bbea 100644 --- a/src/auth-server/docs/Models/ConnectAccountRequestData_allOf.md +++ b/src/auth-server/docs/Models/ChangeAccountRequestData_allOf.md @@ -1,4 +1,4 @@ -# ConnectAccountRequestData_allOf +# ChangeAccountRequestData_allOf ## Properties | Name | Type | Description | Notes | diff --git a/src/auth-server/docs/Models/DisconnectAccountRequestData.md b/src/auth-server/docs/Models/DisconnectAccountRequestData.md deleted file mode 100644 index e223b64ea..000000000 --- a/src/auth-server/docs/Models/DisconnectAccountRequestData.md +++ /dev/null @@ -1,9 +0,0 @@ -# DisconnectAccountRequestData -## Properties - -| Name | Type | Description | Notes | -|------------ | ------------- | ------------- | -------------| -| **joystreamAccountId** | **String** | | [default to null] | - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - diff --git a/src/auth-server/docs/README.md b/src/auth-server/docs/README.md index d0d06b325..a7f237c26 100644 --- a/src/auth-server/docs/README.md +++ b/src/auth-server/docs/README.md @@ -3,21 +3,18 @@ ## Documentation for API Endpoints -All URIs are relative to *http://localhost:4074/api/v1* +All URIs are relative to *http://localhost/api/v1* | Class | Method | HTTP request | Description | |------------ | ------------- | ------------- | -------------| | *DefaultApi* | [**anonymousAuth**](Apis/DefaultApi.md#anonymousauth) | **POST** /anonymous-auth | Authenticate as an anonymous user, either using an existing user identifier or creating a new one. | +*DefaultApi* | [**changeAccount**](Apis/DefaultApi.md#changeaccount) | **POST** /change-account | Change the blockchain (Joystream) account associated with the Gateway account. Delete the old account's encryption artifacts and optionally set new ones. | *DefaultApi* | [**confirmEmail**](Apis/DefaultApi.md#confirmemail) | **POST** /confirm-email | Confirm account's e-mail address provided during registration. | -*DefaultApi* | [**connectAccount**](Apis/DefaultApi.md#connectaccount) | **POST** /connect-account | Connect a Joystream account (key) with the Gateway acount by providing a signed proof of ownership. | *DefaultApi* | [**createAccount**](Apis/DefaultApi.md#createaccount) | **POST** /account | Create a new Gateway account. Requires anonymousAuth to be performed first. | -*DefaultApi* | [**deleteArtifacts**](Apis/DefaultApi.md#deleteartifacts) | **DELETE** /artifacts | Delete wallet seed encryption artifacts in case they are no longer needed. | -*DefaultApi* | [**disconnectAccount**](Apis/DefaultApi.md#disconnectaccount) | **POST** /disconnect-account | Disconnect a Joystream account (key) from the Gateway acount. | *DefaultApi* | [**getArtifacts**](Apis/DefaultApi.md#getartifacts) | **GET** /artifacts | Get wallet seed encryption artifacts. | *DefaultApi* | [**getSessionArtifacts**](Apis/DefaultApi.md#getsessionartifacts) | **GET** /session-artifacts | Get wallet seed encryption artifacts for the current session. | -*DefaultApi* | [**login**](Apis/DefaultApi.md#login) | **POST** /login | Login to user's account by providing a message signed by one of the user's connected accounts. | +*DefaultApi* | [**login**](Apis/DefaultApi.md#login) | **POST** /login | Login to user's account by providing a message signed by the associated blockchain account. | *DefaultApi* | [**logout**](Apis/DefaultApi.md#logout) | **POST** /logout | Terminate the current session. | -*DefaultApi* | [**postArtifacts**](Apis/DefaultApi.md#postartifacts) | **POST** /artifacts | Save wallet seed encryption artifacts associated with the account (if not already saved). | *DefaultApi* | [**postSessionArtifacts**](Apis/DefaultApi.md#postsessionartifacts) | **POST** /session-artifacts | Save wallet seed encryption artifacts for the current session on the server. | *DefaultApi* | [**requestEmailConfirmationToken**](Apis/DefaultApi.md#requestemailconfirmationtoken) | **POST** /request-email-confirmation-token | Request a token to be sent to account's e-mail address, which will allow confirming the ownership of the e-mail by the user. | @@ -30,12 +27,11 @@ All URIs are relative to *http://localhost:4074/api/v1* - [AnonymousUserAuthRequestData](./Models/AnonymousUserAuthRequestData.md) - [AnonymousUserAuthResponseData](./Models/AnonymousUserAuthResponseData.md) - [AnonymousUserAuthResponseData_allOf](./Models/AnonymousUserAuthResponseData_allOf.md) + - [ChangeAccountRequestData](./Models/ChangeAccountRequestData.md) + - [ChangeAccountRequestData_allOf](./Models/ChangeAccountRequestData_allOf.md) - [ConfirmEmailRequestData](./Models/ConfirmEmailRequestData.md) - - [ConnectAccountRequestData](./Models/ConnectAccountRequestData.md) - - [ConnectAccountRequestData_allOf](./Models/ConnectAccountRequestData_allOf.md) - [CreateAccountRequestData](./Models/CreateAccountRequestData.md) - [CreateAccountRequestData_allOf](./Models/CreateAccountRequestData_allOf.md) - - [DisconnectAccountRequestData](./Models/DisconnectAccountRequestData.md) - [EncryptionArtifacts](./Models/EncryptionArtifacts.md) - [GenericErrorResponseData](./Models/GenericErrorResponseData.md) - [GenericOkResponseData](./Models/GenericOkResponseData.md) diff --git a/src/auth-server/generated/api-types.ts b/src/auth-server/generated/api-types.ts index 275349728..a5b821866 100644 --- a/src/auth-server/generated/api-types.ts +++ b/src/auth-server/generated/api-types.ts @@ -80,7 +80,6 @@ export interface components { memberId: string email: string encryptionArtifacts?: components['schemas']['EncryptionArtifacts'] - referrerChannelId?: string } } ChangeAccountRequestData: components['schemas']['ActionExecutionRequestData'] & { diff --git a/src/auth-server/handlers/createAccount.ts b/src/auth-server/handlers/createAccount.ts index 165e45c1f..096927fa3 100644 --- a/src/auth-server/handlers/createAccount.ts +++ b/src/auth-server/handlers/createAccount.ts @@ -1,12 +1,12 @@ import express from 'express' -import { BadRequestError, ConflictError, NotFoundError } from '../errors' -import { components } from '../generated/api-types' -import { globalEm } from '../../utils/globalEm' import { Account, EncryptionArtifacts, Membership, NextEntityId } from '../../model' import { AuthContext } from '../../utils/auth' +import { globalEm } from '../../utils/globalEm' import { idStringFromNumber } from '../../utils/misc' -import { verifyActionExecutionRequest } from '../utils' import { defaultNotificationPreferences } from '../../utils/notification/helpers' +import { BadRequestError, ConflictError, NotFoundError } from '../errors' +import { components } from '../generated/api-types' +import { verifyActionExecutionRequest } from '../utils' type ReqParams = Record type ResBody = @@ -22,7 +22,7 @@ export const createAccount: ( ) => Promise = async (req, res, next) => { try { const { - payload: { email, memberId, joystreamAccountId, referrerChannelId }, + payload: { email, memberId, joystreamAccountId }, } = req.body const { authContext } = res.locals const em = await globalEm @@ -88,7 +88,7 @@ export const createAccount: ( joystreamAccount: joystreamAccountId, membershipId: memberId.toString(), notificationPreferences, - referrerChannelId: referrerChannelId || null, + referrerChannelId: null, }) await em.save([ diff --git a/src/server-extension/resolvers/AdminResolver/index.ts b/src/server-extension/resolvers/AdminResolver/index.ts index 5a3b4991e..b7ea62db1 100644 --- a/src/server-extension/resolvers/AdminResolver/index.ts +++ b/src/server-extension/resolvers/AdminResolver/index.ts @@ -17,6 +17,7 @@ import { Account, Channel, ChannelRecipient, + CreatorToken, NftFeaturedOnMarketPlace, OperatorPermission, OwnedNft, @@ -50,6 +51,8 @@ import { SetCategoryFeaturedVideosArgs, SetCategoryFeaturedVideosResult, SetChannelsWeightsArgs, + SetFeaturedCrtsInput, + SetFeaturedCrtsResult, SetFeaturedNftsInput, SetFeaturedNftsResult, SetKillSwitchInput, @@ -400,6 +403,36 @@ export class AdminResolver { return await setFeaturedNftsInner(em, featuredNftsIds) } + @UseMiddleware(OperatorOnly(OperatorPermission.SET_FEATURED_CRTS)) + @Mutation(() => SetFeaturedCrtsResult) + async setFeaturedCrts( + @Args() { featuredCrtsIds }: SetFeaturedCrtsInput + ): Promise { + const em = await this.em() + let newNumberOfCrtsFeatured = 0 + + await em + .createQueryBuilder() + .update(CreatorToken) + .set({ isFeatured: false }) + .where({ isFeatured: true }) + .execute() + + if (featuredCrtsIds.length) { + const result = await em + .createQueryBuilder() + .update(CreatorToken) + .set({ isFeatured: true }) + .where({ id: In(featuredCrtsIds) }) + .execute() + newNumberOfCrtsFeatured = result.affected || 0 + } + + return { + newNumberOfCrtsFeatured, + } + } + @UseMiddleware(OperatorOnly(OperatorPermission.EXCLUDE_CONTENT)) @Mutation(() => ExcludeContentResult) async excludeContent( diff --git a/src/server-extension/resolvers/AdminResolver/types.ts b/src/server-extension/resolvers/AdminResolver/types.ts index b5526e85a..8a9099f8b 100644 --- a/src/server-extension/resolvers/AdminResolver/types.ts +++ b/src/server-extension/resolvers/AdminResolver/types.ts @@ -281,6 +281,14 @@ export class SetFeaturedNftsInput { featuredNftsIds: string[] } +@ArgsType() +export class SetFeaturedCrtsInput { + @Field(() => [String], { + description: 'IDs of the CRTs that should be featured by the Gateway', + }) + featuredCrtsIds: string[] +} + @ObjectType() export class SetFeaturedNftsResult { @Field(() => Int, { @@ -290,6 +298,15 @@ export class SetFeaturedNftsResult { newNumberOfNftsFeatured?: number } +@ObjectType() +export class SetFeaturedCrtsResult { + @Field(() => Int, { + nullable: true, + description: 'The updated number of crts that are now explicitly featured by the Gateway', + }) + newNumberOfCrtsFeatured?: number +} + @ArgsType() export class SetNewAppAssetStorageInput { @Field(() => String, {