diff --git a/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 b/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 index 238b44226e4..2ddd4d8c8a2 100644 --- a/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 +++ b/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 @@ -544,6 +544,17 @@ data: "upsert": true } );' + mongosh $DATABASE__URL --quiet --eval 'db.getCollection("external-tools").updateOne( + { + "name": "Merlin Bibliothek", + }, + { $set: { + "config_secret": "'$CTL_SEED_SECRET_MERLIN'", + } }, + { + "upsert": true + } + );' echo "Inserted ctl seed data secrets to external-tools." # ========== End of the CTL seed data configuration section. diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/README.md b/apps/server/src/modules/common-cartridge/common-cartridge-client/README.md index 136b6686d6c..f1f5a586a7b 100644 --- a/apps/server/src/modules/common-cartridge/common-cartridge-client/README.md +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/README.md @@ -4,7 +4,7 @@ You can run the script with a parameter, which is the path to the controller you For example: ```bash -node ./scripts/filter-spec.js /courses +node ./scripts/filter_spec-apis.js /courses ``` The execution of the script will generate a new file in the script folder called **filtered-spec.json** with the filtered specification to the controller, you have passed as a parameter. This file should be used to generate the client code for the controller you want to use and should be **deleted** after that. This script is also able to just select used models and operations from the swagger specification. Unused models will be ignored. diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.adapter.spec.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.adapter.spec.ts new file mode 100644 index 00000000000..418896d1a22 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.adapter.spec.ts @@ -0,0 +1,92 @@ +import { faker } from '@faker-js/faker'; +import { createMock, DeepMocked } from '@golevelup/ts-jest'; +import { REQUEST } from '@nestjs/core'; +import { Test, TestingModule } from '@nestjs/testing'; +import { AxiosResponse } from 'axios'; +import { Request } from 'express'; +import { UnauthorizedException } from '@nestjs/common'; +import { CardListResponse, CardResponse } from './cards-api-client/models'; +import { CardClientAdapter } from './card-client.adapter'; +import { BoardCardApi } from './cards-api-client'; + +describe(CardClientAdapter.name, () => { + const jwtToken = faker.string.alphanumeric(20); + let module: TestingModule; + let adapterUnderTest: CardClientAdapter; + let cardApiMock: DeepMocked; + + beforeAll(async () => { + module = await Test.createTestingModule({ + providers: [ + CardClientAdapter, + { + provide: BoardCardApi, + useValue: createMock(), + }, + { + provide: REQUEST, + useValue: createMock({ + headers: { + authorization: `Bearer ${jwtToken}`, + }, + }), + }, + ], + }).compile(); + adapterUnderTest = module.get(CardClientAdapter); + cardApiMock = module.get(BoardCardApi); + }); + + afterAll(async () => { + await module.close(); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('CardClientAdapter should be defind', () => { + expect(adapterUnderTest).toBeDefined(); + }); + + describe('getAllBoardCardsByIds', () => { + describe('when getAllBoardCardsByIds is called', () => { + const setup = () => { + const cardResponseData: CardResponse[] = []; + const data: CardListResponse = { data: cardResponseData }; + const response = createMock>({ + data, + }); + + cardApiMock.cardControllerGetCards.mockResolvedValue(response); + + return faker.string.uuid(); + }; + + it('it should return a list of card response', async () => { + const ids: Array = new Array(setup()); + await adapterUnderTest.getAllBoardCardsByIds(ids); + expect(cardApiMock.cardControllerGetCards).toHaveBeenCalled(); + }); + }); + }); + + describe('When no JWT token is found', () => { + const setup = () => { + const ids: Array = new Array(faker.string.uuid()); + const request = createMock({ + headers: {}, + }); + + const adapter: CardClientAdapter = new CardClientAdapter(cardApiMock, request); + + return { ids, adapter }; + }; + + it('should throw an UnauthorizedError', async () => { + const { ids, adapter } = setup(); + + await expect(adapter.getAllBoardCardsByIds(ids)).rejects.toThrowError(UnauthorizedException); + }); + }); +}); diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.adapter.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.adapter.ts new file mode 100644 index 00000000000..41e689dee38 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.adapter.ts @@ -0,0 +1,39 @@ +import { Inject, Injectable, UnauthorizedException } from '@nestjs/common'; +import { extractJwtFromHeader } from '@shared/common'; +import { RawAxiosRequestConfig } from 'axios'; +import { Request } from 'express'; +import { REQUEST } from '@nestjs/core'; +import { BoardCardApi } from './cards-api-client'; +import { CardListResponseDto } from './dto/card-list-response.dto'; +import { CardResponseMapper } from './mapper/card-response.mapper'; + +@Injectable() +export class CardClientAdapter { + constructor(private readonly boardCardApi: BoardCardApi, @Inject(REQUEST) private request: Request) {} + + public async getAllBoardCardsByIds(cardsIds: string[]): Promise { + const options = this.createOptionParams(); + const getBoardCardsResponse = await this.boardCardApi + .cardControllerGetCards(cardsIds, options) + .then((response) => response.data); + + return CardResponseMapper.mapToCardListResponseDto(getBoardCardsResponse); + } + + private createOptionParams(): RawAxiosRequestConfig { + const jwt = this.getJwt(); + const options: RawAxiosRequestConfig = { headers: { authorization: `Bearer ${jwt}` } }; + + return options; + } + + private getJwt(): string { + const jwt = extractJwtFromHeader(this.request) ?? this.request.headers.authorization; + + if (!jwt) { + throw new UnauthorizedException('No JWT found in request'); + } + + return jwt; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.config.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.config.ts new file mode 100644 index 00000000000..62c9df75dc2 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.config.ts @@ -0,0 +1,5 @@ +import { ConfigurationParameters } from './cards-api-client'; + +export interface CardClientConfig extends ConfigurationParameters { + basePath?: string; +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.module.spec.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.module.spec.ts new file mode 100644 index 00000000000..badf66780f8 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.module.spec.ts @@ -0,0 +1,28 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { CardClientModule } from './card-client.module'; +import { CardClientAdapter } from './card-client.adapter'; + +describe('CardClientModule', () => { + let module: TestingModule; + + beforeAll(async () => { + module = await Test.createTestingModule({ + imports: [ + CardClientModule.register({ + basePath: 'http://localhost:3030/api/v3', + }), + ], + }).compile(); + }); + + afterAll(async () => { + await module.close(); + }); + + describe('when module is initialized', () => { + it('should have the CardClientAdapter defined', () => { + const cardClientAdapter = module.get(CardClientAdapter); + expect(cardClientAdapter).toBeDefined(); + }); + }); +}); diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.module.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.module.ts new file mode 100644 index 00000000000..b7e81f8fb4b --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/card-client.module.ts @@ -0,0 +1,25 @@ +import { DynamicModule, Module } from '@nestjs/common'; +import { CardClientConfig } from './card-client.config'; +import { CardClientAdapter } from './card-client.adapter'; +import { BoardCardApi, Configuration } from './cards-api-client'; + +@Module({}) +export class CardClientModule { + static register(config: CardClientConfig): DynamicModule { + const providers = [ + CardClientAdapter, + { + provide: BoardCardApi, + useFactory: () => { + const configuration = new Configuration(config); + return new BoardCardApi(configuration); + }, + }, + ]; + return { + module: CardClientModule, + providers, + exports: [CardClientAdapter], + }; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.gitignore b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.gitignore new file mode 100644 index 00000000000..149b5765472 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.npmignore b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.npmignore new file mode 100644 index 00000000000..999d88df693 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.npmignore @@ -0,0 +1 @@ +# empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm \ No newline at end of file diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.openapi-generator-ignore b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.openapi-generator/FILES b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.openapi-generator/FILES new file mode 100644 index 00000000000..87cd4d4af4d --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/.openapi-generator/FILES @@ -0,0 +1,37 @@ +.gitignore +.npmignore +api.ts +api/board-card-api.ts +base.ts +common.ts +configuration.ts +git_push.sh +index.ts +models/api-validation-error.ts +models/card-controller-create-element201-response.ts +models/card-list-response.ts +models/card-response-elements-inner.ts +models/card-response.ts +models/collaborative-text-editor-element-response.ts +models/content-element-type.ts +models/create-content-element-body-params.ts +models/deleted-element-content.ts +models/deleted-element-response.ts +models/drawing-element-content.ts +models/drawing-element-response.ts +models/external-tool-element-content.ts +models/external-tool-element-response.ts +models/file-element-content.ts +models/file-element-response.ts +models/index.ts +models/link-element-content.ts +models/link-element-response.ts +models/move-card-body-params.ts +models/rename-body-params.ts +models/rich-text-element-content.ts +models/rich-text-element-response.ts +models/set-height-body-params.ts +models/submission-container-element-content.ts +models/submission-container-element-response.ts +models/timestamps-response.ts +models/visibility-settings-response.ts diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/api.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/api.ts new file mode 100644 index 00000000000..3d36f53648d --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/api.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +export * from './api/board-card-api'; + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/api/board-card-api.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/api/board-card-api.ts new file mode 100644 index 00000000000..71fc8373be5 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/api/board-card-api.ts @@ -0,0 +1,158 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.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 type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { ApiValidationError } from '../models'; +// @ts-ignore +import type { CardListResponse } from '../models'; +/** + * BoardCardApi - axios parameter creator + * @export + */ +export const BoardCardApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Get a list of cards by their ids. + * @param {Array} ids Array of Ids to be loaded + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + cardControllerGetCards: async (ids: Array, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'ids' is not null or undefined + assertParamExists('cardControllerGetCards', 'ids', ids) + const localVarPath = `/cards`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + if (ids) { + localVarQueryParameter['ids'] = ids; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * BoardCardApi - functional programming interface + * @export + */ +export const BoardCardApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = BoardCardApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Get a list of cards by their ids. + * @param {Array} ids Array of Ids to be loaded + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async cardControllerGetCards(ids: Array, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.cardControllerGetCards(ids, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BoardCardApi.cardControllerGetCards']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * BoardCardApi - factory interface + * @export + */ +export const BoardCardApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = BoardCardApiFp(configuration) + return { + /** + * + * @summary Get a list of cards by their ids. + * @param {Array} ids Array of Ids to be loaded + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + cardControllerGetCards(ids: Array, options?: any): AxiosPromise { + return localVarFp.cardControllerGetCards(ids, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * BoardCardApi - interface + * @export + * @interface BoardCardApi + */ +export interface BoardCardApiInterface { + /** + * + * @summary Get a list of cards by their ids. + * @param {Array} ids Array of Ids to be loaded + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BoardCardApiInterface + */ + cardControllerGetCards(ids: Array, options?: RawAxiosRequestConfig): AxiosPromise; + +} + +/** + * BoardCardApi - object-oriented interface + * @export + * @class BoardCardApi + * @extends {BaseAPI} + */ +export class BoardCardApi extends BaseAPI implements BoardCardApiInterface { + /** + * + * @summary Get a list of cards by their ids. + * @param {Array} ids Array of Ids to be loaded + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BoardCardApi + */ + public cardControllerGetCards(ids: Array, options?: RawAxiosRequestConfig) { + return BoardCardApiFp(this.configuration).cardControllerGetCards(ids, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/base.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/base.ts new file mode 100644 index 00000000000..82686c7b81b --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/base.ts @@ -0,0 +1,86 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.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 type { Configuration } from './configuration'; +// Some imports not used depending on template conditions +// @ts-ignore +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; + +export const BASE_PATH = "http://localhost/api/v3".replace(/\/+$/, ""); + +/** + * + * @export + */ +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +/** + * + * @export + * @interface RequestArgs + */ +export interface RequestArgs { + url: string; + options: RawAxiosRequestConfig; +} + +/** + * + * @export + * @class BaseAPI + */ +export class BaseAPI { + protected configuration: Configuration | undefined; + + constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) { + if (configuration) { + this.configuration = configuration; + this.basePath = configuration.basePath ?? basePath; + } + } +}; + +/** + * + * @export + * @class RequiredError + * @extends {Error} + */ +export class RequiredError extends Error { + constructor(public field: string, msg?: string) { + super(msg); + this.name = "RequiredError" + } +} + +interface ServerMap { + [key: string]: { + url: string, + description: string, + }[]; +} + +/** + * + * @export + */ +export const operationServerMap: ServerMap = { +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/common.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/common.ts new file mode 100644 index 00000000000..6c119efb60d --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/common.ts @@ -0,0 +1,150 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.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 type { Configuration } from "./configuration"; +import type { RequestArgs } from "./base"; +import type { AxiosInstance, AxiosResponse } from 'axios'; +import { RequiredError } from "./base"; + +/** + * + * @export + */ +export const DUMMY_BASE_URL = 'https://example.com' + +/** + * + * @throws {RequiredError} + * @export + */ +export const assertParamExists = function (functionName: string, paramName: string, paramValue: unknown) { + if (paramValue === null || paramValue === undefined) { + throw new RequiredError(paramName, `Required parameter ${paramName} was null or undefined when calling ${functionName}.`); + } +} + +/** + * + * @export + */ +export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) { + if (configuration && configuration.apiKey) { + const localVarApiKeyValue = typeof configuration.apiKey === 'function' + ? await configuration.apiKey(keyParamName) + : await configuration.apiKey; + object[keyParamName] = localVarApiKeyValue; + } +} + +/** + * + * @export + */ +export const setBasicAuthToObject = function (object: any, configuration?: Configuration) { + if (configuration && (configuration.username || configuration.password)) { + object["auth"] = { username: configuration.username, password: configuration.password }; + } +} + +/** + * + * @export + */ +export const setBearerAuthToObject = async function (object: any, configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const accessToken = typeof configuration.accessToken === 'function' + ? await configuration.accessToken() + : await configuration.accessToken; + object["Authorization"] = "Bearer " + accessToken; + } +} + +/** + * + * @export + */ +export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const localVarAccessTokenValue = typeof configuration.accessToken === 'function' + ? await configuration.accessToken(name, scopes) + : await configuration.accessToken; + object["Authorization"] = "Bearer " + localVarAccessTokenValue; + } +} + +function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void { + if (parameter == null) return; + if (typeof parameter === "object") { + if (Array.isArray(parameter)) { + (parameter as any[]).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); + } + else { + Object.keys(parameter).forEach(currentKey => + setFlattenedQueryParams(urlSearchParams, parameter[currentKey], `${key}${key !== '' ? '.' : ''}${currentKey}`) + ); + } + } + else { + if (urlSearchParams.has(key)) { + urlSearchParams.append(key, parameter); + } + else { + urlSearchParams.set(key, parameter); + } + } +} + +/** + * + * @export + */ +export const setSearchParams = function (url: URL, ...objects: any[]) { + const searchParams = new URLSearchParams(url.search); + setFlattenedQueryParams(searchParams, objects); + url.search = searchParams.toString(); +} + +/** + * + * @export + */ +export const serializeDataIfNeeded = function (value: any, requestOptions: any, configuration?: Configuration) { + const nonString = typeof value !== 'string'; + const needsSerialization = nonString && configuration && configuration.isJsonMime + ? configuration.isJsonMime(requestOptions.headers['Content-Type']) + : nonString; + return needsSerialization + ? JSON.stringify(value !== undefined ? value : {}) + : (value || ""); +} + +/** + * + * @export + */ +export const toPathString = function (url: URL) { + return url.pathname + url.search + url.hash +} + +/** + * + * @export + */ +export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) { + return >(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs = {...axiosArgs.options, url: (axios.defaults.baseURL ? '' : configuration?.basePath ?? basePath) + axiosArgs.url}; + return axios.request(axiosRequestArgs); + }; +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/configuration.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/configuration.ts new file mode 100644 index 00000000000..8c97d307cf4 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/configuration.ts @@ -0,0 +1,110 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export interface ConfigurationParameters { + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + username?: string; + password?: string; + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + basePath?: string; + serverIndex?: number; + baseOptions?: any; + formDataCtor?: new () => any; +} + +export class Configuration { + /** + * parameter for apiKey security + * @param name security name + * @memberof Configuration + */ + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + /** + * parameter for basic security + * + * @type {string} + * @memberof Configuration + */ + username?: string; + /** + * parameter for basic security + * + * @type {string} + * @memberof Configuration + */ + password?: string; + /** + * parameter for oauth2 security + * @param name security name + * @param scopes oauth2 scope + * @memberof Configuration + */ + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + /** + * override base path + * + * @type {string} + * @memberof Configuration + */ + basePath?: string; + /** + * override server index + * + * @type {number} + * @memberof Configuration + */ + serverIndex?: number; + /** + * base options for axios calls + * + * @type {any} + * @memberof Configuration + */ + baseOptions?: any; + /** + * The FormData constructor that will be used to create multipart form data + * requests. You can inject this here so that execution environments that + * do not support the FormData class can still run the generated client. + * + * @type {new () => FormData} + */ + formDataCtor?: new () => any; + + constructor(param: ConfigurationParameters = {}) { + this.apiKey = param.apiKey; + this.username = param.username; + this.password = param.password; + this.accessToken = param.accessToken; + this.basePath = param.basePath; + this.serverIndex = param.serverIndex; + this.baseOptions = param.baseOptions; + this.formDataCtor = param.formDataCtor; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/git_push.sh b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/git_push.sh new file mode 100644 index 00000000000..f53a75d4fab --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/index.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/index.ts new file mode 100644 index 00000000000..8b762df664e --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/index.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export * from "./api"; +export * from "./configuration"; +export * from "./models"; diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/api-validation-error.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/api-validation-error.ts new file mode 100644 index 00000000000..3f49cf86f0d --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/api-validation-error.ts @@ -0,0 +1,54 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface ApiValidationError + */ +export interface ApiValidationError { + /** + * The response status code. + * @type {number} + * @memberof ApiValidationError + */ + 'code': number; + /** + * The error type. + * @type {string} + * @memberof ApiValidationError + */ + 'type': string; + /** + * The error title. + * @type {string} + * @memberof ApiValidationError + */ + 'title': string; + /** + * The error message. + * @type {string} + * @memberof ApiValidationError + */ + 'message': string; + /** + * The error details. + * @type {object} + * @memberof ApiValidationError + */ + 'details'?: object; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-controller-create-element201-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-controller-create-element201-response.ts new file mode 100644 index 00000000000..8d5e118691e --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-controller-create-element201-response.ts @@ -0,0 +1,53 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { DeletedElementContent } from './deleted-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { DeletedElementResponse } from './deleted-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { DrawingElementResponse } from './drawing-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { ExternalToolElementResponse } from './external-tool-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { FileElementResponse } from './file-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { LinkElementResponse } from './link-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { RichTextElementResponse } from './rich-text-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { SubmissionContainerElementResponse } from './submission-container-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * @type CardControllerCreateElement201Response + * @export + */ +export type CardControllerCreateElement201Response = DeletedElementResponse | DrawingElementResponse | ExternalToolElementResponse | FileElementResponse | LinkElementResponse | RichTextElementResponse | SubmissionContainerElementResponse; + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-list-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-list-response.ts new file mode 100644 index 00000000000..d3127c46646 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-list-response.ts @@ -0,0 +1,33 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { CardResponse } from './card-response'; + +/** + * + * @export + * @interface CardListResponse + */ +export interface CardListResponse { + /** + * + * @type {Array} + * @memberof CardListResponse + */ + 'data': Array; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-response-elements-inner.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-response-elements-inner.ts new file mode 100644 index 00000000000..5111cd49e11 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-response-elements-inner.ts @@ -0,0 +1,56 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { CollaborativeTextEditorElementResponse } from './collaborative-text-editor-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { DeletedElementContent } from './deleted-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { DeletedElementResponse } from './deleted-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { DrawingElementResponse } from './drawing-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { ExternalToolElementResponse } from './external-tool-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { FileElementResponse } from './file-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { LinkElementResponse } from './link-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { RichTextElementResponse } from './rich-text-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { SubmissionContainerElementResponse } from './submission-container-element-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * @type CardResponseElementsInner + * @export + */ +export type CardResponseElementsInner = CollaborativeTextEditorElementResponse | DeletedElementResponse | DrawingElementResponse | ExternalToolElementResponse | FileElementResponse | LinkElementResponse | RichTextElementResponse | SubmissionContainerElementResponse; + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-response.ts new file mode 100644 index 00000000000..93f03bf3e78 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/card-response.ts @@ -0,0 +1,69 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { CardResponseElementsInner } from './card-response-elements-inner'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { VisibilitySettingsResponse } from './visibility-settings-response'; + +/** + * + * @export + * @interface CardResponse + */ +export interface CardResponse { + /** + * + * @type {string} + * @memberof CardResponse + */ + 'id': string; + /** + * + * @type {string} + * @memberof CardResponse + */ + 'title'?: string; + /** + * + * @type {number} + * @memberof CardResponse + */ + 'height': number; + /** + * + * @type {Array} + * @memberof CardResponse + */ + 'elements': Array; + /** + * + * @type {VisibilitySettingsResponse} + * @memberof CardResponse + */ + 'visibilitySettings': VisibilitySettingsResponse; + /** + * + * @type {TimestampsResponse} + * @memberof CardResponse + */ + 'timestamps': TimestampsResponse; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/collaborative-text-editor-element-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/collaborative-text-editor-element-response.ts new file mode 100644 index 00000000000..83f02148bea --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/collaborative-text-editor-element-response.ts @@ -0,0 +1,56 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * + * @export + * @interface CollaborativeTextEditorElementResponse + */ +export interface CollaborativeTextEditorElementResponse { + /** + * + * @type {string} + * @memberof CollaborativeTextEditorElementResponse + */ + 'id': string; + /** + * + * @type {ContentElementType} + * @memberof CollaborativeTextEditorElementResponse + */ + 'type': ContentElementType; + /** + * + * @type {TimestampsResponse} + * @memberof CollaborativeTextEditorElementResponse + */ + 'timestamps': TimestampsResponse; + /** + * + * @type {object} + * @memberof CollaborativeTextEditorElementResponse + */ + 'content': object; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/content-element-type.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/content-element-type.ts new file mode 100644 index 00000000000..391ec522db3 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/content-element-type.ts @@ -0,0 +1,37 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @enum {string} + */ + +export const ContentElementType = { + FILE: 'file', + DRAWING: 'drawing', + LINK: 'link', + RICH_TEXT: 'richText', + SUBMISSION_CONTAINER: 'submissionContainer', + EXTERNAL_TOOL: 'externalTool', + COLLABORATIVE_TEXT_EDITOR: 'collaborativeTextEditor', + DELETED: 'deleted' +} as const; + +export type ContentElementType = typeof ContentElementType[keyof typeof ContentElementType]; + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/create-content-element-body-params.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/create-content-element-body-params.ts new file mode 100644 index 00000000000..d3dc356aebf --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/create-content-element-body-params.ts @@ -0,0 +1,41 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; + +/** + * + * @export + * @interface CreateContentElementBodyParams + */ +export interface CreateContentElementBodyParams { + /** + * + * @type {ContentElementType} + * @memberof CreateContentElementBodyParams + */ + 'type': ContentElementType; + /** + * to bring element to a specific position, default is last position + * @type {number} + * @memberof CreateContentElementBodyParams + */ + 'toPosition'?: number; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/deleted-element-content.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/deleted-element-content.ts new file mode 100644 index 00000000000..a5837dcbef9 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/deleted-element-content.ts @@ -0,0 +1,47 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; + +/** + * + * @export + * @interface DeletedElementContent + */ +export interface DeletedElementContent { + /** + * + * @type {string} + * @memberof DeletedElementContent + */ + 'title': string; + /** + * + * @type {ContentElementType} + * @memberof DeletedElementContent + */ + 'deletedElementType': ContentElementType; + /** + * + * @type {string} + * @memberof DeletedElementContent + */ + 'description': string; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/deleted-element-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/deleted-element-response.ts new file mode 100644 index 00000000000..271ee47be8a --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/deleted-element-response.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { DeletedElementContent } from './deleted-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * + * @export + * @interface DeletedElementResponse + */ +export interface DeletedElementResponse { + /** + * + * @type {string} + * @memberof DeletedElementResponse + */ + 'id': string; + /** + * + * @type {ContentElementType} + * @memberof DeletedElementResponse + */ + 'type': ContentElementType; + /** + * + * @type {DeletedElementContent} + * @memberof DeletedElementResponse + */ + 'content': DeletedElementContent; + /** + * + * @type {TimestampsResponse} + * @memberof DeletedElementResponse + */ + 'timestamps': TimestampsResponse; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/drawing-element-content.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/drawing-element-content.ts new file mode 100644 index 00000000000..dda7fca8f5d --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/drawing-element-content.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface DrawingElementContent + */ +export interface DrawingElementContent { + /** + * + * @type {string} + * @memberof DrawingElementContent + */ + 'description': string; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/drawing-element-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/drawing-element-response.ts new file mode 100644 index 00000000000..b65f9714169 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/drawing-element-response.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { DrawingElementContent } from './drawing-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * + * @export + * @interface DrawingElementResponse + */ +export interface DrawingElementResponse { + /** + * + * @type {string} + * @memberof DrawingElementResponse + */ + 'id': string; + /** + * + * @type {ContentElementType} + * @memberof DrawingElementResponse + */ + 'type': ContentElementType; + /** + * + * @type {TimestampsResponse} + * @memberof DrawingElementResponse + */ + 'timestamps': TimestampsResponse; + /** + * + * @type {DrawingElementContent} + * @memberof DrawingElementResponse + */ + 'content': DrawingElementContent; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/external-tool-element-content.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/external-tool-element-content.ts new file mode 100644 index 00000000000..357ab4ae07e --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/external-tool-element-content.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface ExternalToolElementContent + */ +export interface ExternalToolElementContent { + /** + * + * @type {string} + * @memberof ExternalToolElementContent + */ + 'contextExternalToolId': string | null; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/external-tool-element-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/external-tool-element-response.ts new file mode 100644 index 00000000000..fb6f4b60fd0 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/external-tool-element-response.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { ExternalToolElementContent } from './external-tool-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * + * @export + * @interface ExternalToolElementResponse + */ +export interface ExternalToolElementResponse { + /** + * + * @type {string} + * @memberof ExternalToolElementResponse + */ + 'id': string; + /** + * + * @type {ContentElementType} + * @memberof ExternalToolElementResponse + */ + 'type': ContentElementType; + /** + * + * @type {ExternalToolElementContent} + * @memberof ExternalToolElementResponse + */ + 'content': ExternalToolElementContent; + /** + * + * @type {TimestampsResponse} + * @memberof ExternalToolElementResponse + */ + 'timestamps': TimestampsResponse; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/file-element-content.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/file-element-content.ts new file mode 100644 index 00000000000..fd8c90b8352 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/file-element-content.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface FileElementContent + */ +export interface FileElementContent { + /** + * + * @type {string} + * @memberof FileElementContent + */ + 'caption': string; + /** + * + * @type {string} + * @memberof FileElementContent + */ + 'alternativeText': string; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/file-element-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/file-element-response.ts new file mode 100644 index 00000000000..8e3c2b8ffff --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/file-element-response.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { FileElementContent } from './file-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * + * @export + * @interface FileElementResponse + */ +export interface FileElementResponse { + /** + * + * @type {string} + * @memberof FileElementResponse + */ + 'id': string; + /** + * + * @type {ContentElementType} + * @memberof FileElementResponse + */ + 'type': ContentElementType; + /** + * + * @type {FileElementContent} + * @memberof FileElementResponse + */ + 'content': FileElementContent; + /** + * + * @type {TimestampsResponse} + * @memberof FileElementResponse + */ + 'timestamps': TimestampsResponse; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/index.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/index.ts new file mode 100644 index 00000000000..c68fe9f28ba --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/index.ts @@ -0,0 +1,27 @@ +export * from './api-validation-error'; +export * from './card-controller-create-element201-response'; +export * from './card-list-response'; +export * from './card-response'; +export * from './card-response-elements-inner'; +export * from './collaborative-text-editor-element-response'; +export * from './content-element-type'; +export * from './create-content-element-body-params'; +export * from './deleted-element-content'; +export * from './deleted-element-response'; +export * from './drawing-element-content'; +export * from './drawing-element-response'; +export * from './external-tool-element-content'; +export * from './external-tool-element-response'; +export * from './file-element-content'; +export * from './file-element-response'; +export * from './link-element-content'; +export * from './link-element-response'; +export * from './move-card-body-params'; +export * from './rename-body-params'; +export * from './rich-text-element-content'; +export * from './rich-text-element-response'; +export * from './set-height-body-params'; +export * from './submission-container-element-content'; +export * from './submission-container-element-response'; +export * from './timestamps-response'; +export * from './visibility-settings-response'; diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/link-element-content.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/link-element-content.ts new file mode 100644 index 00000000000..298c02b7a88 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/link-element-content.ts @@ -0,0 +1,48 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface LinkElementContent + */ +export interface LinkElementContent { + /** + * + * @type {string} + * @memberof LinkElementContent + */ + 'url': string; + /** + * + * @type {string} + * @memberof LinkElementContent + */ + 'title': string; + /** + * + * @type {string} + * @memberof LinkElementContent + */ + 'description'?: string; + /** + * + * @type {string} + * @memberof LinkElementContent + */ + 'imageUrl'?: string; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/link-element-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/link-element-response.ts new file mode 100644 index 00000000000..9ce6c6958e0 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/link-element-response.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { LinkElementContent } from './link-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * + * @export + * @interface LinkElementResponse + */ +export interface LinkElementResponse { + /** + * + * @type {string} + * @memberof LinkElementResponse + */ + 'id': string; + /** + * + * @type {ContentElementType} + * @memberof LinkElementResponse + */ + 'type': ContentElementType; + /** + * + * @type {LinkElementContent} + * @memberof LinkElementResponse + */ + 'content': LinkElementContent; + /** + * + * @type {TimestampsResponse} + * @memberof LinkElementResponse + */ + 'timestamps': TimestampsResponse; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/move-card-body-params.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/move-card-body-params.ts new file mode 100644 index 00000000000..56c4bdac0f6 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/move-card-body-params.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface MoveCardBodyParams + */ +export interface MoveCardBodyParams { + /** + * + * @type {string} + * @memberof MoveCardBodyParams + */ + 'toColumnId': string; + /** + * + * @type {number} + * @memberof MoveCardBodyParams + */ + 'toPosition': number; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rename-body-params.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rename-body-params.ts new file mode 100644 index 00000000000..1c52e3f08f9 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rename-body-params.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface RenameBodyParams + */ +export interface RenameBodyParams { + /** + * + * @type {string} + * @memberof RenameBodyParams + */ + 'title': string; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rich-text-element-content.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rich-text-element-content.ts new file mode 100644 index 00000000000..c1c1deec6c4 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rich-text-element-content.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface RichTextElementContent + */ +export interface RichTextElementContent { + /** + * + * @type {string} + * @memberof RichTextElementContent + */ + 'text': string; + /** + * + * @type {string} + * @memberof RichTextElementContent + */ + 'inputFormat': string; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rich-text-element-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rich-text-element-response.ts new file mode 100644 index 00000000000..b46c3b623e2 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/rich-text-element-response.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { RichTextElementContent } from './rich-text-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * + * @export + * @interface RichTextElementResponse + */ +export interface RichTextElementResponse { + /** + * + * @type {string} + * @memberof RichTextElementResponse + */ + 'id': string; + /** + * + * @type {ContentElementType} + * @memberof RichTextElementResponse + */ + 'type': ContentElementType; + /** + * + * @type {RichTextElementContent} + * @memberof RichTextElementResponse + */ + 'content': RichTextElementContent; + /** + * + * @type {TimestampsResponse} + * @memberof RichTextElementResponse + */ + 'timestamps': TimestampsResponse; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/set-height-body-params.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/set-height-body-params.ts new file mode 100644 index 00000000000..c74c7e490bf --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/set-height-body-params.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface SetHeightBodyParams + */ +export interface SetHeightBodyParams { + /** + * + * @type {number} + * @memberof SetHeightBodyParams + */ + 'height': number; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/submission-container-element-content.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/submission-container-element-content.ts new file mode 100644 index 00000000000..dd0b9a949f6 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/submission-container-element-content.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface SubmissionContainerElementContent + */ +export interface SubmissionContainerElementContent { + /** + * The dueDate as date string or null of not set + * @type {string} + * @memberof SubmissionContainerElementContent + */ + 'dueDate': string; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/submission-container-element-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/submission-container-element-response.ts new file mode 100644 index 00000000000..4c3001c303b --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/submission-container-element-response.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ContentElementType } from './content-element-type'; +// May contain unused imports in some cases +// @ts-ignore +import type { SubmissionContainerElementContent } from './submission-container-element-content'; +// May contain unused imports in some cases +// @ts-ignore +import type { TimestampsResponse } from './timestamps-response'; + +/** + * + * @export + * @interface SubmissionContainerElementResponse + */ +export interface SubmissionContainerElementResponse { + /** + * + * @type {string} + * @memberof SubmissionContainerElementResponse + */ + 'id': string; + /** + * + * @type {ContentElementType} + * @memberof SubmissionContainerElementResponse + */ + 'type': ContentElementType; + /** + * + * @type {SubmissionContainerElementContent} + * @memberof SubmissionContainerElementResponse + */ + 'content': SubmissionContainerElementContent; + /** + * + * @type {TimestampsResponse} + * @memberof SubmissionContainerElementResponse + */ + 'timestamps': TimestampsResponse; +} + + + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/timestamps-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/timestamps-response.ts new file mode 100644 index 00000000000..2da93bfa411 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/timestamps-response.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface TimestampsResponse + */ +export interface TimestampsResponse { + /** + * + * @type {string} + * @memberof TimestampsResponse + */ + 'lastUpdatedAt': string; + /** + * + * @type {string} + * @memberof TimestampsResponse + */ + 'createdAt': string; + /** + * + * @type {string} + * @memberof TimestampsResponse + */ + 'deletedAt'?: string; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/visibility-settings-response.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/visibility-settings-response.ts new file mode 100644 index 00000000000..91baa51c30b --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/cards-api-client/models/visibility-settings-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schulcloud-Verbund-Software Server API + * This is v3 of Schulcloud-Verbund-Software Server. Checkout /docs for v1. + * + * The version of the OpenAPI document: 3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface VisibilitySettingsResponse + */ +export interface VisibilitySettingsResponse { + /** + * + * @type {string} + * @memberof VisibilitySettingsResponse + */ + 'publishedAt'?: string; +} + diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/card-list-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/card-list-response.dto.ts new file mode 100644 index 00000000000..ce011649d1b --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/card-list-response.dto.ts @@ -0,0 +1,9 @@ +import { CardResponseDto } from './card-response.dto'; + +export class CardListResponseDto { + data: CardResponseDto[]; + + constructor(data: CardResponseDto[]) { + this.data = data; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/card-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/card-response.dto.ts new file mode 100644 index 00000000000..2139dfcbd1e --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/card-response.dto.ts @@ -0,0 +1,33 @@ +import { CardResponseElementsInnerDto } from '../types/card-response-elements-inner.type'; +import { TimestampResponseDto } from './timestamp-response.dto'; +import { VisibilitySettingsResponseDto } from './visibility-settings-response.dto'; + +export class CardResponseDto { + id: string; + + title?: string; + + height: number; + + elements: Array; + + visibilitySettings: VisibilitySettingsResponseDto; + + timeStamps: TimestampResponseDto; + + constructor( + id: string, + title: string, + height: number, + elements: CardResponseElementsInnerDto[], + visibilitySettings: VisibilitySettingsResponseDto, + timestamps: TimestampResponseDto + ) { + this.id = id; + this.title = title; + this.height = height; + this.elements = elements; + this.visibilitySettings = visibilitySettings; + this.timeStamps = timestamps; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/collaborative-text-editor-element-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/collaborative-text-editor-element-response.dto.ts new file mode 100644 index 00000000000..7d864480759 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/collaborative-text-editor-element-response.dto.ts @@ -0,0 +1,19 @@ +import { ContentElementType } from '../cards-api-client'; +import { TimestampResponseDto } from './timestamp-response.dto'; + +export class CollaborativeTextEditorElementResponseDto { + id: string; + + type: ContentElementType; + + timestamps: TimestampResponseDto; + + content: object; + + constructor(id: string, type: ContentElementType, content: object, timestamps: TimestampResponseDto) { + this.id = id; + this.type = type; + this.timestamps = timestamps; + this.content = content; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/deleted-element-content.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/deleted-element-content.dto.ts new file mode 100644 index 00000000000..3bd24f9967f --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/deleted-element-content.dto.ts @@ -0,0 +1,15 @@ +import { ContentElementType } from '../enums/content-element-type.enum'; + +export class DeletedElementContentDto { + title: string; + + deletedElementType: ContentElementType; + + description: string; + + constructor(title: string, deletedElementType: ContentElementType, description: string) { + this.title = title; + this.deletedElementType = deletedElementType; + this.description = description; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/deleted-element-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/deleted-element-response.dto.ts new file mode 100644 index 00000000000..74eee786bc6 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/deleted-element-response.dto.ts @@ -0,0 +1,25 @@ +import { ContentElementType } from '../cards-api-client'; +import { DeletedElementContentDto } from './deleted-element-content.dto'; +import { TimestampResponseDto } from './timestamp-response.dto'; + +export class DeletedElementResponseDto { + id: string; + + type: ContentElementType; + + content: DeletedElementContentDto; + + timestamps: TimestampResponseDto; + + constructor( + id: string, + type: ContentElementType, + content: DeletedElementContentDto, + timestamps: TimestampResponseDto + ) { + this.id = id; + this.type = type; + this.content = content; + this.timestamps = timestamps; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/drawing-element-content.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/drawing-element-content.dto.ts new file mode 100644 index 00000000000..4291bf7d44a --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/drawing-element-content.dto.ts @@ -0,0 +1,7 @@ +export class DrawingElementContentDto { + descritpion: string; + + constructor(descritpion: string) { + this.descritpion = descritpion; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/drawing-element-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/drawing-element-response.dto.ts new file mode 100644 index 00000000000..a658f9de525 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/drawing-element-response.dto.ts @@ -0,0 +1,25 @@ +import { ContentElementType } from '../enums/content-element-type.enum'; +import { DrawingElementContentDto } from './drawing-element-content.dto'; +import { TimestampResponseDto } from './timestamp-response.dto'; + +export class DrawingElementResponseDto { + id: string; + + type: ContentElementType; + + timestamps: TimestampResponseDto; + + content: DrawingElementContentDto; + + constructor( + id: string, + type: ContentElementType, + content: DrawingElementContentDto, + timestamps: TimestampResponseDto + ) { + this.id = id; + this.type = type; + this.timestamps = timestamps; + this.content = content; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/external-tool-element-content.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/external-tool-element-content.dto.ts new file mode 100644 index 00000000000..a820a16701f --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/external-tool-element-content.dto.ts @@ -0,0 +1,7 @@ +export class ExternalToolElementContentDto { + contentExternalToolId: string | null; + + constructor(contentExternalToolId: string | null) { + this.contentExternalToolId = contentExternalToolId; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/external-tool-element-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/external-tool-element-response.dto.ts new file mode 100644 index 00000000000..054b0be68f5 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/external-tool-element-response.dto.ts @@ -0,0 +1,25 @@ +import { ContentElementType } from '../enums/content-element-type.enum'; +import { ExternalToolElementContentDto } from './external-tool-element-content.dto'; +import { TimestampResponseDto } from './timestamp-response.dto'; + +export class ExternalToolElementResponseDto { + id: string; + + type: ContentElementType; + + content: ExternalToolElementContentDto; + + timestamps: TimestampResponseDto; + + constructor( + id: string, + type: ContentElementType, + content: ExternalToolElementContentDto, + timestamps: TimestampResponseDto + ) { + this.id = id; + this.type = type; + this.content = content; + this.timestamps = timestamps; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/file-element-content.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/file-element-content.dto.ts new file mode 100644 index 00000000000..58d16071444 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/file-element-content.dto.ts @@ -0,0 +1,10 @@ +export class FileElementContentDto { + caption: string; + + alternativeText: string; + + constructor(caption: string, alternativeText: string) { + this.caption = caption; + this.alternativeText = alternativeText; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/file-element-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/file-element-response.dto.ts new file mode 100644 index 00000000000..66dc3b44579 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/file-element-response.dto.ts @@ -0,0 +1,20 @@ +import { ContentElementType } from '../enums/content-element-type.enum'; +import { FileElementContentDto } from './file-element-content.dto'; +import { TimestampResponseDto } from './timestamp-response.dto'; + +export class FileElementResponseDto { + id: string; + + type: ContentElementType; + + content: FileElementContentDto; + + timestamps: TimestampResponseDto; + + constructor(id: string, type: ContentElementType, content: FileElementContentDto, timestamps: TimestampResponseDto) { + this.id = id; + this.type = type; + this.content = content; + this.timestamps = timestamps; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/link-element-content.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/link-element-content.dto.ts new file mode 100644 index 00000000000..6b257248f30 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/link-element-content.dto.ts @@ -0,0 +1,16 @@ +export class LinkElementContentDto { + url: string; + + title: string; + + description?: string; + + imageUrl?: string; + + constructor(url: string, title: string, description: string, imageUrl: string) { + this.url = url; + this.title = title; + this.description = description; + this.imageUrl = imageUrl; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/link-element-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/link-element-response.dto.ts new file mode 100644 index 00000000000..4c4fa40a48a --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/link-element-response.dto.ts @@ -0,0 +1,20 @@ +import { ContentElementType } from '../enums/content-element-type.enum'; +import { LinkElementContentDto } from './link-element-content.dto'; +import { TimestampResponseDto } from './timestamp-response.dto'; + +export class LinkElementResponseDto { + id: string; + + type: ContentElementType; + + content: LinkElementContentDto; + + timestamps: TimestampResponseDto; + + constructor(id: string, type: ContentElementType, content: LinkElementContentDto, timestamps: TimestampResponseDto) { + this.id = id; + this.type = type; + this.content = content; + this.timestamps = timestamps; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/rich-text-element-content.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/rich-text-element-content.dto.ts new file mode 100644 index 00000000000..7726852b1dd --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/rich-text-element-content.dto.ts @@ -0,0 +1,10 @@ +export class RichTextElementContentDto { + text: string; + + inputFormat: string; + + constructor(text: string, inputFormat: string) { + this.text = text; + this.inputFormat = inputFormat; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/rich-text-element-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/rich-text-element-response.dto.ts new file mode 100644 index 00000000000..b8e5c3811b5 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/rich-text-element-response.dto.ts @@ -0,0 +1,25 @@ +import { ContentElementType } from '../enums/content-element-type.enum'; +import { RichTextElementContentDto } from './rich-text-element-content.dto'; +import { TimestampResponseDto } from './timestamp-response.dto'; + +export class RichTextElementResponseDto { + id: string; + + type: ContentElementType; + + content: RichTextElementContentDto; + + timestamps: TimestampResponseDto; + + constructor( + id: string, + type: ContentElementType, + content: RichTextElementContentDto, + timestamps: TimestampResponseDto + ) { + this.id = id; + this.type = type; + this.content = content; + this.timestamps = timestamps; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/submission-container-element-content.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/submission-container-element-content.dto.ts new file mode 100644 index 00000000000..75742befce9 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/submission-container-element-content.dto.ts @@ -0,0 +1,7 @@ +export class SubmissionContainerElementContentDto { + dueDate?: string; + + constructor(dueDate: string) { + this.dueDate = dueDate; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/submission-container-element-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/submission-container-element-response.dto.ts new file mode 100644 index 00000000000..8b208ab5a12 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/submission-container-element-response.dto.ts @@ -0,0 +1,25 @@ +import { ContentElementType } from '../cards-api-client'; +import { SubmissionContainerElementContentDto } from './submission-container-element-content.dto'; +import { TimestampResponseDto } from './timestamp-response.dto'; + +export class SubmissionContainerElementResponseDto { + id: string; + + type: ContentElementType; + + content: SubmissionContainerElementContentDto; + + timestamps: TimestampResponseDto; + + constructor( + id: string, + type: ContentElementType, + content: SubmissionContainerElementContentDto, + timestamps: TimestampResponseDto + ) { + this.id = id; + this.type = type; + this.content = content; + this.timestamps = timestamps; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/timestamp-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/timestamp-response.dto.ts new file mode 100644 index 00000000000..a75998154b1 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/timestamp-response.dto.ts @@ -0,0 +1,13 @@ +export class TimestampResponseDto { + lastUpdatedAt: string; + + createdAt: string; + + deletedAt?: string; + + constructor(lastUpdatedAt: string, createdAt: string, deletedAt: string) { + this.lastUpdatedAt = lastUpdatedAt; + this.createdAt = createdAt; + this.deletedAt = deletedAt; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/visibility-settings-response.dto.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/visibility-settings-response.dto.ts new file mode 100644 index 00000000000..8497fe79a4e --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/dto/visibility-settings-response.dto.ts @@ -0,0 +1,7 @@ +export class VisibilitySettingsResponseDto { + publishedAt?: string; + + constructor(publishedAt: string) { + this.publishedAt = publishedAt; + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/enums/content-element-type.enum.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/enums/content-element-type.enum.ts new file mode 100644 index 00000000000..773c63fdbe9 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/enums/content-element-type.enum.ts @@ -0,0 +1,10 @@ +export enum ContentElementType { + FILE = 'file', + DRAWING = 'drawing', + LINK = 'link', + RICH_TEXT = 'richText', + SUBMISSION_CONTAINER = 'submissionContainer', + EXTERNAL_TOOL = 'externalTool', + COLLABORATIVE_TEXT_EDITOR = 'collaborativeTextEditor', + DELETED = 'deleted', +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/mapper/card-response.mapper.spec.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/mapper/card-response.mapper.spec.ts new file mode 100644 index 00000000000..29052e30911 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/mapper/card-response.mapper.spec.ts @@ -0,0 +1,188 @@ +import { faker } from '@faker-js/faker'; +import { CardResponseMapper } from './card-response.mapper'; +import { + CardListResponse, + DeletedElementResponse, + SubmissionContainerElementResponse, + DrawingElementResponse, + ExternalToolElementResponse, + FileElementResponse, + LinkElementResponse, + RichTextElementResponse, + CollaborativeTextEditorElementResponse, + CardResponseElementsInner, +} from '../cards-api-client'; +import { ContentElementType } from '../enums/content-element-type.enum'; +import { CardContentElementInner } from '../types/card-content-elements-inner.type'; +import { CardResponseDto } from '../dto/card-response.dto'; + +describe('CardResponseMapper', () => { + const createMockElement = ( + id: string, + type: ContentElementType, + content: CardContentElementInner + ): CardContentElementInner => { + const element: CardContentElementInner = { + id, + type, + content, + timestamps: { + lastUpdatedAt: faker.date.recent().toISOString(), + createdAt: faker.date.soon().toISOString(), + deletedAt: null, + }, + }; + + return element; + }; + + describe('mapToCardListResponseDto', () => { + const setup = (elementsArray: CardResponseElementsInner[]) => { + const mockCardListResponse: CardListResponse = { + data: [ + { + id: 'card-1', + title: 'Card 1', + height: 100, + elements: elementsArray, + visibilitySettings: { publishedAt: '2024-10-03T12:00:00Z' }, + timestamps: { + lastUpdatedAt: '2024-10-03T11:00:00Z', + createdAt: faker.date.recent().toISOString(), + deletedAt: faker.date.recent().toString(), + }, + }, + ], + }; + return mockCardListResponse; + }; + + describe("when various elements' responses are sent to mapper", () => { + const mockList: CardListResponse = setup([ + createMockElement( + faker.string.uuid(), + ContentElementType.COLLABORATIVE_TEXT_EDITOR, + {} + ) as CollaborativeTextEditorElementResponse, + + createMockElement(faker.string.uuid(), ContentElementType.DELETED, { + title: faker.lorem.sentence(), + description: faker.lorem.words(), + }) as DeletedElementResponse, + + createMockElement(faker.string.uuid(), ContentElementType.SUBMISSION_CONTAINER, { + dueDate: faker.date.soon().toISOString(), + }) as SubmissionContainerElementResponse, + + createMockElement(faker.string.uuid(), ContentElementType.DRAWING, { + description: faker.lorem.word(), + }) as DrawingElementResponse, + + createMockElement(faker.string.uuid(), ContentElementType.EXTERNAL_TOOL, { + contextExternalToolId: faker.string.uuid(), + }) as ExternalToolElementResponse, + + createMockElement(faker.string.uuid(), ContentElementType.FILE, { + caption: faker.lorem.sentence(), + alternativeText: faker.lorem.word(), + }) as FileElementResponse, + + createMockElement(faker.string.uuid(), ContentElementType.LINK, { + url: faker.internet.url(), + title: faker.lorem.word(), + description: faker.lorem.sentence(), + imageUrl: faker.internet.url(), + }) as LinkElementResponse, + + createMockElement(faker.string.uuid(), ContentElementType.RICH_TEXT, { + text: faker.lorem.paragraph(), + inputFormat: faker.internet.domainName(), + }) as RichTextElementResponse, + + createMockElement(faker.string.uuid(), 'UNKNOWN_TYPE' as ContentElementType, {}) as CardResponseElementsInner, + ]); + + it('should map CardListResponse to CardListResponseDto with all types of elements', () => { + const result = CardResponseMapper.mapToCardListResponseDto(mockList); + const cardResponseDto = result.data[0]; + + expect(result).toBeDefined(); + expect(result.data).toHaveLength(1); + expect(cardResponseDto.id).toBe('card-1'); + expect(cardResponseDto.title).toBe('Card 1'); + expect(cardResponseDto.height).toBe(100); + expect(cardResponseDto.visibilitySettings.publishedAt).toBe('2024-10-03T12:00:00Z'); + expect(cardResponseDto.timeStamps.lastUpdatedAt).toBe('2024-10-03T11:00:00Z'); + expect(cardResponseDto.elements).toHaveLength(8); + expect(cardResponseDto.elements[0].type).toBe(ContentElementType.COLLABORATIVE_TEXT_EDITOR); + expect(cardResponseDto.elements[1].type).toBe(ContentElementType.DELETED); + expect(cardResponseDto.elements[2].type).toBe(ContentElementType.SUBMISSION_CONTAINER); + expect(cardResponseDto.elements[3].type).toBe(ContentElementType.DRAWING); + expect(cardResponseDto.elements[4].type).toBe(ContentElementType.EXTERNAL_TOOL); + expect(cardResponseDto.elements[5].type).toBe(ContentElementType.FILE); + expect(cardResponseDto.elements[6].type).toBe(ContentElementType.LINK); + expect(cardResponseDto.elements[7].type).toBe(ContentElementType.RICH_TEXT); + }); + }); + + describe('when there is an unknown element response to handle', () => { + const mockList: CardListResponse = setup([ + createMockElement('element-unknown', 'UNKNOWN_TYPE' as ContentElementType, {}) as CardResponseElementsInner, + ]); + + it('should handle unknown element types without breaking', () => { + const result = CardResponseMapper.mapToCardListResponseDto(mockList); + const cardResponseDto = result.data[0]; + + expect(result).toBeDefined(); + expect(result.data).toHaveLength(1); + expect(cardResponseDto.id).toBe('card-1'); + expect(cardResponseDto.title).toBe('Card 1'); + expect(cardResponseDto.height).toBe(100); + expect(cardResponseDto.elements).toHaveLength(0); + }); + }); + + describe('when CardResponse has no elements', () => { + const mockList: CardListResponse = setup([]); + + it('should return an empty list of elements', () => { + const result = CardResponseMapper.mapToCardListResponseDto(mockList); + const cardResponse: CardResponseDto = result.data[0]; + + expect(result).toBeDefined(); + expect(result.data).toHaveLength(1); + expect(cardResponse.id).toBe('card-1'); + expect(cardResponse.title).toBe('Card 1'); + expect(cardResponse.height).toBe(100); + expect(cardResponse.elements).toHaveLength(0); + expect(cardResponse.visibilitySettings.publishedAt).toBe('2024-10-03T12:00:00Z'); + expect(cardResponse.timeStamps.lastUpdatedAt).toBe('2024-10-03T11:00:00Z'); + }); + }); + + describe('when the publishedAt in visibilitySettings is null', () => { + const mockList: CardListResponse = setup([]); + mockList.data[0].visibilitySettings.publishedAt = undefined; + + it('should return an empty string', () => { + const mapperResult = CardResponseMapper.mapToCardListResponseDto(mockList); + const cardResponse: CardResponseDto = mapperResult.data[0]; + + expect(cardResponse.visibilitySettings.publishedAt).toBe(''); + }); + }); + + describe('when deletedAt in TimestampsResponse is null', () => { + const mockList: CardListResponse = setup([]); + mockList.data[0].timestamps.deletedAt = undefined; + + it('should return an empty string', () => { + const mapperResult = CardResponseMapper.mapToCardListResponseDto(mockList); + const cardResponse: CardResponseDto = mapperResult.data[0]; + + expect(cardResponse.timeStamps.deletedAt).toBe(''); + }); + }); + }); +}); diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/mapper/card-response.mapper.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/mapper/card-response.mapper.ts new file mode 100644 index 00000000000..ecf86629756 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/mapper/card-response.mapper.ts @@ -0,0 +1,175 @@ +import { + CardListResponse, + CardResponse, + CardResponseElementsInner, + VisibilitySettingsResponse, + TimestampsResponse, + DeletedElementContent, + SubmissionContainerElementContent, + DrawingElementContent, + ExternalToolElementContent, + FileElementContent, + LinkElementContent, + RichTextElementContent, +} from '../cards-api-client'; +import { CardResponseDto } from '../dto/card-response.dto'; +import { CollaborativeTextEditorElementResponseDto } from '../dto/collaborative-text-editor-element-response.dto'; +import { DeletedElementResponseDto } from '../dto/deleted-element-response.dto'; +import { DrawingElementContentDto } from '../dto/drawing-element-content.dto'; +import { DrawingElementResponseDto } from '../dto/drawing-element-response.dto'; +import { ExternalToolElementContentDto } from '../dto/external-tool-element-content.dto'; +import { ExternalToolElementResponseDto } from '../dto/external-tool-element-response.dto'; +import { FileElementContentDto } from '../dto/file-element-content.dto'; +import { FileElementResponseDto } from '../dto/file-element-response.dto'; +import { LinkElementContentDto } from '../dto/link-element-content.dto'; +import { LinkElementResponseDto } from '../dto/link-element-response.dto'; +import { RichTextElementContentDto } from '../dto/rich-text-element-content.dto'; +import { RichTextElementResponseDto } from '../dto/rich-text-element-response.dto'; +import { SubmissionContainerElementResponseDto } from '../dto/submission-container-element-response.dto'; +import { ContentElementType } from '../enums/content-element-type.enum'; +import { SubmissionContainerElementContentDto } from '../dto/submission-container-element-content.dto'; +import { DeletedElementContentDto } from '../dto/deleted-element-content.dto'; +import { VisibilitySettingsResponseDto } from '../dto/visibility-settings-response.dto'; +import { TimestampResponseDto } from '../dto/timestamp-response.dto'; +import { CardResponseElementsInnerDto } from '../types/card-response-elements-inner.type'; +import { CardListResponseDto } from '../dto/card-list-response.dto'; + +export class CardResponseMapper { + public static mapToCardListResponseDto(cardListResponse: CardListResponse): CardListResponseDto { + const cardListResponseDto: CardListResponseDto = new CardListResponseDto([]); + + cardListResponse.data.forEach((cardResponse) => { + cardListResponseDto.data.push(this.mapToCardResponseDto(cardResponse)); + }); + return cardListResponseDto; + } + + private static mapToCardResponseDto(cardResponse: CardResponse): CardResponseDto { + return new CardResponseDto( + cardResponse.id, + cardResponse.title ?? '', + cardResponse.height, + this.mapToCardResponseElementsInnerDto(cardResponse.elements), + this.mapToVisibilitySettingsDto(cardResponse.visibilitySettings), + this.mapToTimestampDto(cardResponse.timestamps) + ); + } + + private static mapToCardResponseElementsInnerDto( + cardResponseElementsInner: CardResponseElementsInner[] + ): CardResponseElementsInnerDto[] { + const elements: CardResponseElementsInnerDto[] = []; + + cardResponseElementsInner.forEach((element) => { + switch (element.type) { + case ContentElementType.COLLABORATIVE_TEXT_EDITOR: + elements.push( + new CollaborativeTextEditorElementResponseDto( + element.id, + ContentElementType.COLLABORATIVE_TEXT_EDITOR, + { ...element.content }, + this.mapToTimestampDto(element.timestamps) + ) + ); + break; + case ContentElementType.DELETED: { + const content: DeletedElementContent = element.content as DeletedElementContent; + elements.push( + new DeletedElementResponseDto( + element.id, + ContentElementType.DELETED, + new DeletedElementContentDto(content.title, ContentElementType.DELETED, content.description), + this.mapToTimestampDto(element.timestamps) + ) + ); + break; + } + case ContentElementType.SUBMISSION_CONTAINER: { + const content: SubmissionContainerElementContent = element.content as SubmissionContainerElementContent; + elements.push( + new SubmissionContainerElementResponseDto( + element.id, + ContentElementType.SUBMISSION_CONTAINER, + new SubmissionContainerElementContentDto(content.dueDate), + this.mapToTimestampDto(element.timestamps) + ) + ); + break; + } + case ContentElementType.DRAWING: { + const content: DrawingElementContent = element.content as DrawingElementContent; + elements.push( + new DrawingElementResponseDto( + element.id, + ContentElementType.DRAWING, + new DrawingElementContentDto(content.description), + this.mapToTimestampDto(element.timestamps) + ) + ); + break; + } + case ContentElementType.EXTERNAL_TOOL: { + const content: ExternalToolElementContent = element.content as ExternalToolElementContent; + elements.push( + new ExternalToolElementResponseDto( + element.id, + ContentElementType.EXTERNAL_TOOL, + new ExternalToolElementContentDto(content.contextExternalToolId), + this.mapToTimestampDto(element.timestamps) + ) + ); + break; + } + case ContentElementType.FILE: { + const content: FileElementContent = element.content as FileElementContent; + elements.push( + new FileElementResponseDto( + element.id, + ContentElementType.FILE, + new FileElementContentDto(content.caption, content.alternativeText), + this.mapToTimestampDto(element.timestamps) + ) + ); + break; + } + case ContentElementType.LINK: { + const content: LinkElementContent = element.content as LinkElementContent; + elements.push( + new LinkElementResponseDto( + element.id, + ContentElementType.LINK, + new LinkElementContentDto(content.url, content.title, content.description ?? '', content.imageUrl ?? ''), + this.mapToTimestampDto(element.timestamps) + ) + ); + break; + } + case ContentElementType.RICH_TEXT: { + const content: RichTextElementContent = element.content as RichTextElementContent; + elements.push( + new RichTextElementResponseDto( + element.id, + ContentElementType.RICH_TEXT, + new RichTextElementContentDto(content.text, content.inputFormat), + this.mapToTimestampDto(element.timestamps) + ) + ); + break; + } + default: + break; + } + }); + return elements; + } + + private static mapToVisibilitySettingsDto( + visibilitySettings: VisibilitySettingsResponse + ): VisibilitySettingsResponseDto { + return new VisibilitySettingsResponseDto(visibilitySettings.publishedAt ?? ''); + } + + private static mapToTimestampDto(timestamp: TimestampsResponse): TimestampResponseDto { + return new TimestampResponseDto(timestamp.lastUpdatedAt, timestamp.createdAt, timestamp.deletedAt ?? ''); + } +} diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/types/card-content-elements-inner.type.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/types/card-content-elements-inner.type.ts new file mode 100644 index 00000000000..b8a32bc9479 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/types/card-content-elements-inner.type.ts @@ -0,0 +1,17 @@ +import { DeletedElementContentDto } from '../dto/deleted-element-content.dto'; +import { DrawingElementContentDto } from '../dto/drawing-element-content.dto'; +import { ExternalToolElementContentDto } from '../dto/external-tool-element-content.dto'; +import { FileElementContentDto } from '../dto/file-element-content.dto'; +import { LinkElementContentDto } from '../dto/link-element-content.dto'; +import { RichTextElementContentDto } from '../dto/rich-text-element-content.dto'; +import { SubmissionContainerElementContentDto } from '../dto/submission-container-element-content.dto'; + +export type CardContentElementInner = + | LinkElementContentDto + | DeletedElementContentDto + | DrawingElementContentDto + | ExternalToolElementContentDto + | FileElementContentDto + | RichTextElementContentDto + | SubmissionContainerElementContentDto + | object; diff --git a/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/types/card-response-elements-inner.type.ts b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/types/card-response-elements-inner.type.ts new file mode 100644 index 00000000000..7b4c77dafd8 --- /dev/null +++ b/apps/server/src/modules/common-cartridge/common-cartridge-client/card-client/types/card-response-elements-inner.type.ts @@ -0,0 +1,18 @@ +import { CollaborativeTextEditorElementResponseDto } from '../dto/collaborative-text-editor-element-response.dto'; +import { DeletedElementResponseDto } from '../dto/deleted-element-response.dto'; +import { DrawingElementResponseDto } from '../dto/drawing-element-response.dto'; +import { ExternalToolElementResponseDto } from '../dto/external-tool-element-response.dto'; +import { FileElementResponseDto } from '../dto/file-element-response.dto'; +import { LinkElementResponseDto } from '../dto/link-element-response.dto'; +import { RichTextElementResponseDto } from '../dto/rich-text-element-response.dto'; +import { SubmissionContainerElementResponseDto } from '../dto/submission-container-element-response.dto'; + +export type CardResponseElementsInnerDto = + | CollaborativeTextEditorElementResponseDto + | DeletedElementResponseDto + | DrawingElementResponseDto + | ExternalToolElementResponseDto + | FileElementResponseDto + | LinkElementResponseDto + | RichTextElementResponseDto + | SubmissionContainerElementResponseDto; diff --git a/apps/server/src/modules/common-cartridge/common-cartridge.module.ts b/apps/server/src/modules/common-cartridge/common-cartridge.module.ts index d281bc8af88..babe99d04d3 100644 --- a/apps/server/src/modules/common-cartridge/common-cartridge.module.ts +++ b/apps/server/src/modules/common-cartridge/common-cartridge.module.ts @@ -11,6 +11,7 @@ import { CoursesClientModule } from './common-cartridge-client/course-client'; import { CommonCartridgeExportService } from './service/common-cartridge-export.service'; import { CommonCartridgeUc } from './uc/common-cartridge.uc'; import { CourseRoomsModule } from './common-cartridge-client/room-client'; +import { CardClientModule } from './common-cartridge-client/card-client/card-client.module'; import { LessonClientModule } from './common-cartridge-client/lesson-client/lesson-client.module'; @Module({ @@ -31,6 +32,10 @@ import { LessonClientModule } from './common-cartridge-client/lesson-client/less CourseRoomsModule.register({ basePath: `${Configuration.get('API_HOST') as string}/v3/`, }), + + CardClientModule.register({ + basePath: `${Configuration.get('API_HOST') as string}/v3/`, + }), CoursesClientModule.register({ basePath: `${Configuration.get('API_HOST') as string}/v3/`, }), diff --git a/apps/server/src/modules/common-cartridge/service/common-cartridge-export.service.spec.ts b/apps/server/src/modules/common-cartridge/service/common-cartridge-export.service.spec.ts index 4a1b4b53066..f6d1066f5b0 100644 --- a/apps/server/src/modules/common-cartridge/service/common-cartridge-export.service.spec.ts +++ b/apps/server/src/modules/common-cartridge/service/common-cartridge-export.service.spec.ts @@ -6,6 +6,10 @@ import { BoardClientAdapter } from '../common-cartridge-client/board-client'; import { CommonCartridgeExportService } from './common-cartridge-export.service'; import { CoursesClientAdapter } from '../common-cartridge-client/course-client'; import { CourseRoomsClientAdapter } from '../common-cartridge-client/room-client'; +import { CardClientAdapter } from '../common-cartridge-client/card-client/card-client.adapter'; +import { CardListResponseDto } from '../common-cartridge-client/card-client/dto/card-list-response.dto'; +import { CardResponseDto } from '../common-cartridge-client/card-client/dto/card-response.dto'; +import { ContentElementType } from '../common-cartridge-client/card-client/enums/content-element-type.enum'; describe('CommonCartridgeExportService', () => { let module: TestingModule; @@ -13,6 +17,7 @@ describe('CommonCartridgeExportService', () => { let filesStorageServiceMock: DeepMocked; let coursesClientAdapterMock: DeepMocked; let courseRoomsClientAdapterMock: DeepMocked; + let cardClientAdapterMock: DeepMocked; beforeAll(async () => { module = await Test.createTestingModule({ @@ -34,6 +39,10 @@ describe('CommonCartridgeExportService', () => { provide: CourseRoomsClientAdapter, useValue: createMock(), }, + { + provide: CardClientAdapter, + useValue: createMock(), + }, ], }).compile(); @@ -41,6 +50,7 @@ describe('CommonCartridgeExportService', () => { filesStorageServiceMock = module.get(FilesStorageClientAdapterService); coursesClientAdapterMock = module.get(CoursesClientAdapter); courseRoomsClientAdapterMock = module.get(CourseRoomsClientAdapter); + cardClientAdapterMock = module.get(CardClientAdapter); }); afterAll(async () => { @@ -118,4 +128,48 @@ describe('CommonCartridgeExportService', () => { expect(result).toEqual(expected); }); }); + + describe('findAllCardsByIds', () => { + const setup = () => { + const cardsIds: Array = new Array(faker.string.uuid()); + const mockCard: CardResponseDto = { + id: cardsIds[0], + title: faker.lorem.word(), + height: faker.number.int(), + elements: [ + { + id: 'element-1', + type: ContentElementType.RICH_TEXT, + content: { + text: faker.string.alphanumeric.toString(), + inputFormat: 'HTML', + }, + timestamps: { + lastUpdatedAt: faker.date.anytime.toString(), + createdAt: faker.date.anytime.toString(), + deletedAt: '', + }, + }, + ], + visibilitySettings: { + publishedAt: '2024-10-01T12:00:00Z', + }, + timeStamps: { + lastUpdatedAt: '2024-10-01T11:00:00Z', + createdAt: faker.date.anytime.toString(), + deletedAt: faker.date.anytime.toString(), + }, + }; + const expected: CardListResponseDto = new CardListResponseDto(new Array(mockCard)); + cardClientAdapterMock.getAllBoardCardsByIds.mockResolvedValue(expected); + + return { cardsIds, expected }; + }; + it('should return a card', async () => { + const { cardsIds, expected } = setup(); + const result = await sut.findAllCardsByIds(cardsIds); + + expect(result).toEqual(expected); + }); + }); }); diff --git a/apps/server/src/modules/common-cartridge/service/common-cartridge-export.service.ts b/apps/server/src/modules/common-cartridge/service/common-cartridge-export.service.ts index 9d358dba255..05895643bf1 100644 --- a/apps/server/src/modules/common-cartridge/service/common-cartridge-export.service.ts +++ b/apps/server/src/modules/common-cartridge/service/common-cartridge-export.service.ts @@ -4,12 +4,15 @@ import { BoardClientAdapter } from '../common-cartridge-client/board-client'; import { CourseCommonCartridgeMetadataDto, CoursesClientAdapter } from '../common-cartridge-client/course-client'; import { CourseRoomsClientAdapter } from '../common-cartridge-client/room-client'; import { RoomBoardDto } from '../common-cartridge-client/room-client/dto/room-board.dto'; +import { CardClientAdapter } from '../common-cartridge-client/card-client/card-client.adapter'; +import { CardListResponseDto } from '../common-cartridge-client/card-client/dto/card-list-response.dto'; @Injectable() export class CommonCartridgeExportService { constructor( private readonly filesService: FilesStorageClientAdapterService, private readonly boardClientAdapter: BoardClientAdapter, + private readonly cardClientAdapter: CardClientAdapter, private readonly coursesClientAdapter: CoursesClientAdapter, private readonly courseRoomsClientAdapter: CourseRoomsClientAdapter ) {} @@ -31,4 +34,10 @@ export class CommonCartridgeExportService { return courseRooms; } + + public async findAllCardsByIds(ids: Array): Promise { + const cards = await this.cardClientAdapter.getAllBoardCardsByIds(ids); + + return cards; + } } diff --git a/apps/server/src/modules/idp-console/idp-console.module.ts b/apps/server/src/modules/idp-console/idp-console.module.ts index 84568dcce3d..508d7b514dc 100644 --- a/apps/server/src/modules/idp-console/idp-console.module.ts +++ b/apps/server/src/modules/idp-console/idp-console.module.ts @@ -2,6 +2,7 @@ import { ConsoleWriterModule } from '@infra/console'; import { RabbitMQWrapperModule } from '@infra/rabbitmq'; import { SchulconnexClientModule } from '@infra/schulconnex-client/schulconnex-client.module'; import { MikroOrmModule } from '@mikro-orm/nestjs'; +import { AccountModule } from '@modules/account'; import { defaultMikroOrmOptions } from '@modules/server'; import { SynchronizationEntity, SynchronizationModule } from '@modules/synchronization'; import { UserModule } from '@modules/user'; @@ -30,6 +31,7 @@ import { SynchronizationUc } from './uc'; // debug: true, // use it for locally debugging of queries }), UserModule, + AccountModule, LoggerModule, RabbitMQWrapperModule, ConsoleWriterModule, diff --git a/apps/server/src/modules/idp-console/uc/synchronization.uc.spec.ts b/apps/server/src/modules/idp-console/uc/synchronization.uc.spec.ts index feaf80daf3b..767405c8fd5 100644 --- a/apps/server/src/modules/idp-console/uc/synchronization.uc.spec.ts +++ b/apps/server/src/modules/idp-console/uc/synchronization.uc.spec.ts @@ -13,6 +13,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { setupEntities } from '@shared/testing'; import { createConfigModuleOptions } from '@src/config'; import { Logger } from '@src/core/logger'; +import { AccountService } from '@src/modules/account'; import { ObjectId } from 'bson'; import { FailedUpdateLastSyncedAtLoggableException, @@ -25,6 +26,7 @@ describe(SynchronizationUc.name, () => { let module: TestingModule; let uc: SynchronizationUc; let userService: DeepMocked; + let accountService: DeepMocked; let synchronizationService: DeepMocked; let schulconnexRestClient: DeepMocked; @@ -45,6 +47,10 @@ describe(SynchronizationUc.name, () => { provide: UserService, useValue: createMock(), }, + { + provide: AccountService, + useValue: createMock(), + }, { provide: SchulconnexRestClient, useValue: createMock(), @@ -55,6 +61,7 @@ describe(SynchronizationUc.name, () => { uc = module.get(SynchronizationUc); synchronizationService = module.get(SynchronizationService); userService = module.get(UserService); + accountService = module.get(AccountService); schulconnexRestClient = module.get(SchulconnexRestClient); await setupEntities(); }); @@ -354,26 +361,39 @@ describe(SynchronizationUc.name, () => { const systemId = new ObjectId().toHexString(); const userAId = new ObjectId().toHexString(); const userBId = new ObjectId().toHexString(); - const usersToCheck = [userAId, userBId]; + const userCId = new ObjectId().toHexString(); + const userDId = new ObjectId().toHexString(); + const usersToCheck = [userAId, userBId, userCId, userDId]; + const usersFound = [userAId, userBId, userCId]; const usersToSync = [userAId, userBId]; const userSyncCount = 2; - userService.findByExternalIdsAndProvidedBySystemId.mockResolvedValueOnce(usersToSync); + userService.findMultipleByExternalIds.mockResolvedValueOnce(usersFound); + accountService.findByUserIdsAndSystemId.mockResolvedValueOnce(usersToSync); return { systemId, userSyncCount, usersToCheck, + usersFound, usersToSync, }; }; - it('should call the userService.findByExternalIdsAndProvidedBySystemId to get array of users to sync', async () => { + it('should call the userService.findMultipleByExternalIds to get array of users to sync', async () => { const { systemId, usersToCheck } = setup(); await uc.updateLastSyncedAt(usersToCheck, systemId); - expect(userService.findByExternalIdsAndProvidedBySystemId).toHaveBeenCalledWith(usersToCheck, systemId); + expect(userService.findMultipleByExternalIds).toHaveBeenCalledWith(usersToCheck); + }); + + it('should call the accountService.findByUserIdsAndSystemId confirm users', async () => { + const { systemId, usersToCheck, usersFound } = setup(); + + await uc.updateLastSyncedAt(usersToCheck, systemId); + + expect(accountService.findByUserIdsAndSystemId).toHaveBeenCalledWith(usersFound, systemId); }); it('should call the userService.updateLastSyncedAt to update users', async () => { @@ -401,7 +421,7 @@ describe(SynchronizationUc.name, () => { const usersToCheck = [userAId, userBId]; const usersToSync = [userAId, userBId]; - userService.findByExternalIdsAndProvidedBySystemId.mockResolvedValueOnce(usersToSync); + userService.findMultipleByExternalIds.mockResolvedValueOnce(usersToSync); const error = new Error('testError'); const expectedError = new FailedUpdateLastSyncedAtLoggableException(systemId); diff --git a/apps/server/src/modules/idp-console/uc/synchronization.uc.ts b/apps/server/src/modules/idp-console/uc/synchronization.uc.ts index edd53a3aa11..e254da66461 100644 --- a/apps/server/src/modules/idp-console/uc/synchronization.uc.ts +++ b/apps/server/src/modules/idp-console/uc/synchronization.uc.ts @@ -5,6 +5,7 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Logger } from '@src/core/logger'; import { ErrorLogMessage } from '@src/core/logger/types'; +import { AccountService } from '@src/modules/account'; import { SynchronizationConfig } from '../interface'; import { StartSynchronizationLoggable, SucessSynchronizationLoggable } from './loggable'; import { @@ -20,6 +21,7 @@ export class SynchronizationUc { private readonly schulconnexRestClient: SchulconnexRestClient, private readonly synchronizationService: SynchronizationService, private readonly userService: UserService, + private readonly accountService: AccountService, private readonly logger: Logger ) { this.logger.setContext(SynchronizationUc.name); @@ -70,11 +72,13 @@ export class SynchronizationUc { public async updateLastSyncedAt(usersToCheck: string[], systemId: string): Promise { try { - const usersToSync = await this.userService.findByExternalIdsAndProvidedBySystemId(usersToCheck, systemId); + const foundUsers = await this.userService.findMultipleByExternalIds(usersToCheck); - await this.userService.updateLastSyncedAt(usersToSync); + const verifiedUsers = await this.accountService.findByUserIdsAndSystemId(foundUsers, systemId); - return usersToSync.length; + await this.userService.updateLastSyncedAt(verifiedUsers); + + return verifiedUsers.length; } catch { throw new FailedUpdateLastSyncedAtLoggableException(systemId); } diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/context-external-tool.response.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/context-external-tool.response.ts index 0584d6a981d..60145a6d140 100644 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/context-external-tool.response.ts +++ b/apps/server/src/modules/tool/context-external-tool/controller/dto/context-external-tool.response.ts @@ -21,6 +21,9 @@ export class ContextExternalToolResponse { @ApiProperty({ type: [CustomParameterEntryResponse] }) parameters: CustomParameterEntryResponse[] = []; + @ApiPropertyOptional() + logoUrl?: string; + constructor(response: ContextExternalToolResponse) { this.id = response.id; this.schoolToolId = response.schoolToolId; @@ -28,5 +31,6 @@ export class ContextExternalToolResponse { this.contextType = response.contextType; this.displayName = response.displayName; this.parameters = response.parameters; + this.logoUrl = response.logoUrl; } } diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/index.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/index.ts index a41423e9d72..89922cda255 100644 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/index.ts +++ b/apps/server/src/modules/tool/context-external-tool/controller/dto/index.ts @@ -5,4 +5,3 @@ export * from './context-external-tool-context.params'; export * from './context-external-tool.response'; export * from './tool-reference-list.response'; export * from './tool-reference.response'; -export * from './lti11-deep-link'; diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/index.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/index.ts deleted file mode 100644 index 3f3992f0231..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './lti-deep-link.response'; -export * from './lti11-deep-link.params'; diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti-deep-link.response.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti-deep-link.response.ts deleted file mode 100644 index a3de58e49eb..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti-deep-link.response.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; - -export class LtiDeepLinkResponse { - @ApiProperty() - mediaType: string; - - @ApiPropertyOptional() - url?: string; - - @ApiPropertyOptional() - title?: string; - - @ApiPropertyOptional() - text?: string; - - @ApiPropertyOptional() - availableFrom?: Date; - - @ApiPropertyOptional() - availableUntil?: Date; - - @ApiPropertyOptional() - submissionFrom?: Date; - - @ApiPropertyOptional() - submissionUntil?: Date; - - constructor(props: LtiDeepLinkResponse) { - this.mediaType = props.mediaType; - this.url = props.url; - this.title = props.title; - this.text = props.text; - this.availableFrom = props.availableFrom; - this.availableUntil = props.availableUntil; - this.submissionFrom = props.submissionFrom; - this.submissionUntil = props.submissionUntil; - } -} diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-content-item-type.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-content-item-type.ts deleted file mode 100644 index 5764510b9db..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-content-item-type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum Lti11ContentItemType { - CONTENT_ITEM = 'ContentItem', - LTI_LINK_ITEM = 'LtiLinkItem', - FILE_ITEM = 'FileItem', -} diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item-duration.params.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item-duration.params.ts deleted file mode 100644 index 102cc5eb147..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item-duration.params.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ApiPropertyOptional } from '@nestjs/swagger'; -import { IsDate, IsOptional } from 'class-validator'; - -export class Lti11DeepLinkContentItemDurationParams { - @IsOptional() - @IsDate() - @ApiPropertyOptional() - startDatetime?: Date; - - @IsOptional() - @IsDate() - @ApiPropertyOptional() - endDatetime?: Date; -} diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item-list.params.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item-list.params.ts deleted file mode 100644 index 0568988c357..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item-list.params.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { Type } from 'class-transformer'; -import { ArrayMaxSize, IsArray, IsString, ValidateNested } from 'class-validator'; -import { Lti11DeepLinkContentItemParams } from './lti11-deep-link-content-item.params'; - -export class Lti11DeepLinkContentItemListParams { - @IsString() - @ApiProperty() - '@context'!: string; - - @IsArray() - @ArrayMaxSize(1) - @ValidateNested({ each: true }) - @Type(() => Lti11DeepLinkContentItemParams) - '@graph'!: Lti11DeepLinkContentItemParams[]; -} diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item.params.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item.params.ts deleted file mode 100644 index 57027e461f7..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link-content-item.params.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Type } from 'class-transformer'; -import { IsEnum, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator'; -import { Lti11ContentItemType } from './lti11-content-item-type'; -import { Lti11DeepLinkContentItemDurationParams } from './lti11-deep-link-content-item-duration.params'; - -export class Lti11DeepLinkContentItemParams { - @IsEnum(Lti11ContentItemType) - @ApiProperty() - '@type'!: string; - - @IsString() - @ApiProperty() - mediaType!: string; - - @IsOptional() - @IsString() - @ApiPropertyOptional() - url?: string; - - @IsOptional() - @IsString() - @ApiPropertyOptional() - title?: string; - - @IsOptional() - @IsString() - @ApiPropertyOptional() - text?: string; - - @IsOptional() - @ValidateNested() - @Type(() => Lti11DeepLinkContentItemDurationParams) - @ApiPropertyOptional() - available?: Lti11DeepLinkContentItemDurationParams; - - @IsOptional() - @ValidateNested() - @Type(() => Lti11DeepLinkContentItemDurationParams) - @ApiPropertyOptional() - submission?: Lti11DeepLinkContentItemDurationParams; - - @IsOptional() - @IsObject() - @ApiPropertyOptional() - custom?: Record; -} diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link.params.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link.params.ts deleted file mode 100644 index c353c5386e1..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/lti11-deep-link/lti11-deep-link.params.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { StringToObject } from '@shared/controller/transformer/string-to-json.transformer'; -import { Type } from 'class-transformer'; -import { Equals, IsOptional, IsString, ValidateNested } from 'class-validator'; -import { Lti11DeepLinkContentItemListParams } from './lti11-deep-link-content-item-list.params'; - -export class Lti11DeepLinkParams { - @Equals('ContentItemSelection') - @ApiProperty() - lti_message_type!: string; - - @Equals('LTI-1p0') - @ApiProperty() - lti_version!: string; - - @StringToObject(Lti11DeepLinkContentItemListParams) - @IsOptional() - @ValidateNested() - @Type(() => Lti11DeepLinkContentItemListParams) - @ApiPropertyOptional() - content_items?: Lti11DeepLinkContentItemListParams; - - @IsString() - @ApiProperty() - data!: string; - - @Equals('1.0') - @ApiProperty() - oauth_version!: string; - - @IsString() - @ApiProperty() - oauth_nonce!: string; - - @ApiProperty() - oauth_timestamp!: string; - - @Equals('HMAC-SHA1') - @ApiProperty() - oauth_signature_method!: string; - - @IsString() - @ApiProperty() - oauth_consumer_key!: string; - - @IsString() - @ApiProperty() - oauth_signature!: string; -} diff --git a/apps/server/src/modules/tool/context-external-tool/controller/dto/tool-reference.response.ts b/apps/server/src/modules/tool/context-external-tool/controller/dto/tool-reference.response.ts index 1bf876a7228..9f66a020c3d 100644 --- a/apps/server/src/modules/tool/context-external-tool/controller/dto/tool-reference.response.ts +++ b/apps/server/src/modules/tool/context-external-tool/controller/dto/tool-reference.response.ts @@ -1,6 +1,5 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { ContextExternalToolConfigurationStatusResponse } from '../../../common/controller/dto'; -import { LtiDeepLinkResponse } from './lti11-deep-link/lti-deep-link.response'; export class ToolReferenceResponse { @ApiProperty({ nullable: false, required: true, description: 'The id of the tool in the context' }) @@ -29,9 +28,6 @@ export class ToolReferenceResponse { @ApiProperty({ nullable: false, required: true, description: 'Whether the tool should be opened in a new tab' }) openInNewTab: boolean; - @ApiPropertyOptional({ type: LtiDeepLinkResponse }) - ltiDeepLink?: LtiDeepLinkResponse; - @ApiProperty({ type: ContextExternalToolConfigurationStatusResponse, nullable: false, @@ -47,7 +43,6 @@ export class ToolReferenceResponse { this.thumbnailUrl = toolReferenceResponse.thumbnailUrl; this.displayName = toolReferenceResponse.displayName; this.openInNewTab = toolReferenceResponse.openInNewTab; - this.ltiDeepLink = toolReferenceResponse.ltiDeepLink; this.status = toolReferenceResponse.status; } } diff --git a/apps/server/src/modules/tool/context-external-tool/controller/tool-deep-link.controller.ts b/apps/server/src/modules/tool/context-external-tool/controller/tool-deep-link.controller.ts deleted file mode 100644 index bce3160ce71..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/controller/tool-deep-link.controller.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Body, Controller, Param, Post } from '@nestjs/common'; -import { ApiTags } from '@nestjs/swagger'; -import { ContextExternalToolUc } from '../uc'; -import { ContextExternalToolIdParams, Lti11DeepLinkParams } from './dto'; - -@ApiTags('Tool') -@Controller('tools/context-external-tools') -export class ToolDeepLinkController { - constructor(private readonly contextExternalToolUc: ContextExternalToolUc) {} - - @Post(':contextExternalToolId/lti11-deep-link-callback') - async deepLink(): Promise { - return 'https://google.com'; - } -} diff --git a/apps/server/src/modules/tool/context-external-tool/domain/context-external-tool.do.ts b/apps/server/src/modules/tool/context-external-tool/domain/context-external-tool.do.ts index 933a84133b1..0b3a2bf7335 100644 --- a/apps/server/src/modules/tool/context-external-tool/domain/context-external-tool.do.ts +++ b/apps/server/src/modules/tool/context-external-tool/domain/context-external-tool.do.ts @@ -2,7 +2,6 @@ import { AuthorizableObject, DomainObject } from '@shared/domain/domain-object'; import { CustomParameterEntry } from '../../common/domain'; import { SchoolExternalToolRef } from '../../school-external-tool/domain'; import { ContextRef } from './context-ref'; -import { LtiDeepLink } from './lti-deep-link'; export interface ContextExternalToolLaunchable { id?: string; @@ -12,8 +11,6 @@ export interface ContextExternalToolLaunchable { contextRef: ContextRef; parameters: CustomParameterEntry[]; - - ltiDeepLink?: LtiDeepLink; } export interface ContextExternalToolProps extends AuthorizableObject, ContextExternalToolLaunchable { @@ -38,8 +35,4 @@ export class ContextExternalTool extends DomainObject get parameters(): CustomParameterEntry[] { return this.props.parameters; } - - get ltiDeepLink(): LtiDeepLink | undefined { - return this.props.ltiDeepLink; - } } diff --git a/apps/server/src/modules/tool/context-external-tool/domain/lti-deep-link.ts b/apps/server/src/modules/tool/context-external-tool/domain/lti-deep-link.ts deleted file mode 100644 index f2695e92391..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/domain/lti-deep-link.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { CustomParameterEntry } from '../../common/domain'; - -export class LtiDeepLink { - mediaType: string; - - url?: string; - - title?: string; - - text?: string; - - parameters: CustomParameterEntry[]; - - availableFrom?: Date; - - availableUntil?: Date; - - submissionFrom?: Date; - - submissionUntil?: Date; - - constructor(props: LtiDeepLink) { - this.mediaType = props.mediaType; - this.url = props.url; - this.title = props.title; - this.text = props.text; - this.parameters = props.parameters; - this.availableFrom = props.availableFrom; - this.availableUntil = props.availableUntil; - this.submissionFrom = props.submissionFrom; - this.submissionUntil = props.submissionUntil; - } -} diff --git a/apps/server/src/modules/tool/context-external-tool/domain/tool-reference.ts b/apps/server/src/modules/tool/context-external-tool/domain/tool-reference.ts index d6205de1e21..4db5fe8f120 100644 --- a/apps/server/src/modules/tool/context-external-tool/domain/tool-reference.ts +++ b/apps/server/src/modules/tool/context-external-tool/domain/tool-reference.ts @@ -1,5 +1,4 @@ import { ContextExternalToolConfigurationStatus } from '../../common/domain'; -import { LtiDeepLink } from './lti-deep-link'; export class ToolReference { contextToolId: string; @@ -16,8 +15,6 @@ export class ToolReference { status: ContextExternalToolConfigurationStatus; - ltiDeepLink?: LtiDeepLink; - constructor(toolReference: ToolReference) { this.contextToolId = toolReference.contextToolId; this.description = toolReference.description; @@ -26,6 +23,5 @@ export class ToolReference { this.displayName = toolReference.displayName; this.openInNewTab = toolReference.openInNewTab; this.status = toolReference.status; - this.ltiDeepLink = toolReference.ltiDeepLink; } } diff --git a/apps/server/src/modules/tool/context-external-tool/entity/context-external-tool.entity.ts b/apps/server/src/modules/tool/context-external-tool/entity/context-external-tool.entity.ts index bc1ae0937f2..17e415eb7d3 100644 --- a/apps/server/src/modules/tool/context-external-tool/entity/context-external-tool.entity.ts +++ b/apps/server/src/modules/tool/context-external-tool/entity/context-external-tool.entity.ts @@ -1,11 +1,10 @@ import { Embedded, Entity, ManyToOne, Property } from '@mikro-orm/core'; +import { ObjectId } from '@mikro-orm/mongodb'; import { BaseEntityWithTimestamps } from '@shared/domain/entity/base.entity'; import { EntityId } from '@shared/domain/types'; -import { ObjectId } from '@mikro-orm/mongodb'; import { CustomParameterEntryEntity } from '../../common/entity'; import { SchoolExternalToolEntity } from '../../school-external-tool/entity'; import { ContextExternalToolType } from './context-external-tool-type.enum'; -import { LtiDeepLinkEmbeddable } from './lti-deep-link.embeddable'; export interface ContextExternalToolEntityProps { id?: EntityId; @@ -19,8 +18,6 @@ export interface ContextExternalToolEntityProps { displayName?: string; parameters?: CustomParameterEntryEntity[]; - - ltiDeepLink?: LtiDeepLinkEmbeddable; } @Entity({ tableName: 'context-external-tools' }) @@ -40,9 +37,6 @@ export class ContextExternalToolEntity extends BaseEntityWithTimestamps { @Embedded(() => CustomParameterEntryEntity, { array: true }) parameters: CustomParameterEntryEntity[]; - @Embedded(() => LtiDeepLinkEmbeddable, { nullable: true, object: true }) - ltiDeepLink?: LtiDeepLinkEmbeddable; - constructor(props: ContextExternalToolEntityProps) { super(); if (props.id) { @@ -53,6 +47,5 @@ export class ContextExternalToolEntity extends BaseEntityWithTimestamps { this.contextType = props.contextType; this.displayName = props.displayName; this.parameters = props.parameters ?? []; - this.ltiDeepLink = props.ltiDeepLink; } } diff --git a/apps/server/src/modules/tool/context-external-tool/entity/index.ts b/apps/server/src/modules/tool/context-external-tool/entity/index.ts index faf30b0f1b3..cc6609164e4 100644 --- a/apps/server/src/modules/tool/context-external-tool/entity/index.ts +++ b/apps/server/src/modules/tool/context-external-tool/entity/index.ts @@ -1,3 +1,2 @@ export * from './context-external-tool.entity'; export * from './context-external-tool-type.enum'; -export { LtiDeepLinkEmbeddable } from './lti-deep-link.embeddable'; diff --git a/apps/server/src/modules/tool/context-external-tool/entity/lti-deep-link.embeddable.ts b/apps/server/src/modules/tool/context-external-tool/entity/lti-deep-link.embeddable.ts deleted file mode 100644 index 13aa4472d8e..00000000000 --- a/apps/server/src/modules/tool/context-external-tool/entity/lti-deep-link.embeddable.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Embeddable, Embedded, Property } from '@mikro-orm/core'; -import { CustomParameterEntryEntity } from '../../common/entity'; - -@Embeddable() -export class LtiDeepLinkEmbeddable { - @Property() - mediaType: string; - - @Property({ nullable: true }) - url?: string; - - @Property({ nullable: true }) - title?: string; - - @Property({ nullable: true }) - text?: string; - - @Embedded(() => CustomParameterEntryEntity, { array: true }) - parameters: CustomParameterEntryEntity[]; - - @Property({ nullable: true }) - availableFrom?: Date; - - @Property({ nullable: true }) - availableUntil?: Date; - - @Property({ nullable: true }) - submissionFrom?: Date; - - @Property({ nullable: true }) - submissionUntil?: Date; - - constructor(props: LtiDeepLinkEmbeddable) { - this.mediaType = props.mediaType; - this.url = props.url; - this.title = props.title; - this.text = props.text; - this.parameters = props.parameters; - this.availableFrom = props.availableFrom; - this.availableUntil = props.availableUntil; - this.submissionFrom = props.submissionFrom; - this.submissionUntil = props.submissionUntil; - } -} diff --git a/apps/server/src/modules/tool/context-external-tool/mapper/context-external-tool-response.mapper.ts b/apps/server/src/modules/tool/context-external-tool/mapper/context-external-tool-response.mapper.ts index 744ed6ecaa0..0da038d6124 100644 --- a/apps/server/src/modules/tool/context-external-tool/mapper/context-external-tool-response.mapper.ts +++ b/apps/server/src/modules/tool/context-external-tool/mapper/context-external-tool-response.mapper.ts @@ -1,7 +1,6 @@ -import { ToolStatusResponseMapper } from '../../common/mapper'; +import { ToolStatusResponseMapper } from '../../common/mapper/tool-status-response.mapper'; import { CustomParameterEntryParam, CustomParameterEntryResponse } from '../../school-external-tool/controller/dto'; import { ContextExternalToolResponse, ToolReferenceResponse } from '../controller/dto'; -import { LtiDeepLinkResponse } from '../controller/dto/lti11-deep-link/lti-deep-link.response'; import { ContextExternalTool, ToolReference } from '../domain'; export class ContextExternalToolResponseMapper { @@ -44,21 +43,7 @@ export class ContextExternalToolResponseMapper { } static mapToToolReferenceResponse(toolReference: ToolReference): ToolReferenceResponse { - const { ltiDeepLink } = toolReference; - const ltiDeepLinkResponse: LtiDeepLinkResponse | undefined = ltiDeepLink - ? new LtiDeepLinkResponse({ - mediaType: ltiDeepLink.mediaType, - url: ltiDeepLink.url, - title: ltiDeepLink.title, - text: ltiDeepLink.text, - availableFrom: ltiDeepLink.availableFrom, - availableUntil: ltiDeepLink.availableUntil, - submissionFrom: ltiDeepLink.submissionFrom, - submissionUntil: ltiDeepLink.submissionUntil, - }) - : undefined; - - const response: ToolReferenceResponse = new ToolReferenceResponse({ + const response = new ToolReferenceResponse({ contextToolId: toolReference.contextToolId, description: toolReference.description, displayName: toolReference.displayName, @@ -66,7 +51,6 @@ export class ContextExternalToolResponseMapper { thumbnailUrl: toolReference.thumbnailUrl, openInNewTab: toolReference.openInNewTab, status: ToolStatusResponseMapper.mapToResponse(toolReference.status), - ltiDeepLink: ltiDeepLinkResponse, }); return response; diff --git a/apps/server/src/modules/tool/context-external-tool/uc/context-external-tool.uc.ts b/apps/server/src/modules/tool/context-external-tool/uc/context-external-tool.uc.ts index b206bf854e4..dbea96596d3 100644 --- a/apps/server/src/modules/tool/context-external-tool/uc/context-external-tool.uc.ts +++ b/apps/server/src/modules/tool/context-external-tool/uc/context-external-tool.uc.ts @@ -5,12 +5,10 @@ import { ForbiddenLoggableException, } from '@modules/authorization'; import { AuthorizableReferenceType } from '@modules/authorization/domain'; -import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { Inject, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { User } from '@shared/domain/entity'; import { Permission } from '@shared/domain/interface'; import { EntityId } from '@shared/domain/types'; -import { Cache } from 'cache-manager'; import { ToolContextType } from '../../common/enum'; import { ToolPermissionHelper } from '../../common/uc/tool-permission-helper'; import { SchoolExternalTool } from '../../school-external-tool/domain'; @@ -27,8 +25,7 @@ export class ContextExternalToolUc { private readonly schoolExternalToolService: SchoolExternalToolService, private readonly contextExternalToolService: ContextExternalToolService, private readonly contextExternalToolValidationService: ContextExternalToolValidationService, - private readonly authorizationService: AuthorizationService, - @Inject(CACHE_MANAGER) private readonly cacheManager: Cache + private readonly authorizationService: AuthorizationService ) {} async createContextExternalTool( diff --git a/apps/server/src/modules/tool/tool-api.module.ts b/apps/server/src/modules/tool/tool-api.module.ts index 478d12e618a..51eec1332ff 100644 --- a/apps/server/src/modules/tool/tool-api.module.ts +++ b/apps/server/src/modules/tool/tool-api.module.ts @@ -1,4 +1,3 @@ -import { CacheWrapperModule } from '@infra/cache'; import { EncryptionModule } from '@infra/encryption'; import { AuthorizationModule } from '@modules/authorization'; import { BoardModule } from '@modules/board'; @@ -13,7 +12,6 @@ import { LearnroomModule } from '../learnroom'; import { CommonToolModule } from './common'; import { ToolPermissionHelper } from './common/uc/tool-permission-helper'; import { ToolContextController } from './context-external-tool/controller'; -import { ToolDeepLinkController } from './context-external-tool/controller/tool-deep-link.controller'; import { ToolReferenceController } from './context-external-tool/controller/tool-reference.controller'; import { ContextExternalToolUc, ToolReferenceUc } from './context-external-tool/uc'; import { ToolConfigurationController, ToolController } from './external-tool/controller'; @@ -39,7 +37,6 @@ import { ToolModule } from './tool.module'; SchoolModule, UserLicenseModule, EncryptionModule, - CacheWrapperModule, ], controllers: [ ToolLaunchController, @@ -47,7 +44,6 @@ import { ToolModule } from './tool.module'; ToolSchoolController, ToolContextController, ToolReferenceController, - ToolDeepLinkController, ToolController, ], providers: [ diff --git a/apps/server/src/modules/tool/tool-launch/controller/dto/tool-launch-request.response.ts b/apps/server/src/modules/tool/tool-launch/controller/dto/tool-launch-request.response.ts index 203878e69d5..a488bca921a 100644 --- a/apps/server/src/modules/tool/tool-launch/controller/dto/tool-launch-request.response.ts +++ b/apps/server/src/modules/tool/tool-launch/controller/dto/tool-launch-request.response.ts @@ -30,7 +30,7 @@ export class ToolLaunchRequestResponse { openNewTab?: boolean; @ApiProperty({ - description: 'Specifies whether the Tool should be launched in a new tab', + description: 'Specifies whether the request is an LTI Deep linking content item selection request', }) isDeepLink: boolean; diff --git a/apps/server/src/modules/tool/tool-launch/mapper/tool-launch.mapper.spec.ts b/apps/server/src/modules/tool/tool-launch/mapper/tool-launch.mapper.spec.ts index f11ecc5aa89..9a095fbf116 100644 --- a/apps/server/src/modules/tool/tool-launch/mapper/tool-launch.mapper.spec.ts +++ b/apps/server/src/modules/tool/tool-launch/mapper/tool-launch.mapper.spec.ts @@ -1,7 +1,7 @@ +import { CustomParameterLocation, ToolConfigType } from '../../common/enum'; import { ToolLaunchRequestResponse } from '../controller/dto'; import { LaunchRequestMethod, PropertyLocation, ToolLaunchDataType, ToolLaunchRequest } from '../types'; import { ToolLaunchMapper } from './tool-launch.mapper'; -import { CustomParameterLocation, ToolConfigType } from '../../common/enum'; describe('ToolLaunchMapper', () => { describe('mapToParameterLocation', () => { diff --git a/apps/server/src/modules/tool/tool-launch/mapper/tool-launch.mapper.ts b/apps/server/src/modules/tool/tool-launch/mapper/tool-launch.mapper.ts index 25f5e797a7c..816509c4ff6 100644 --- a/apps/server/src/modules/tool/tool-launch/mapper/tool-launch.mapper.ts +++ b/apps/server/src/modules/tool/tool-launch/mapper/tool-launch.mapper.ts @@ -14,38 +14,22 @@ const toolConfigTypeToToolLaunchDataTypeMapping: Record = { - [ToolLaunchDataType.BASIC]: ToolConfigType.BASIC, - [ToolLaunchDataType.LTI11]: ToolConfigType.LTI11, - [ToolLaunchDataType.OAUTH2]: ToolConfigType.OAUTH2, -}; - export class ToolLaunchMapper { static mapToParameterLocation(location: CustomParameterLocation): PropertyLocation { const mappedLocation = customToParameterLocationMapping[location]; + return mappedLocation; } static mapToToolLaunchDataType(configType: ToolConfigType): ToolLaunchDataType { const mappedType = toolConfigTypeToToolLaunchDataTypeMapping[configType]; - return mappedType; - } - static mapToToolConfigType(launchDataType: ToolLaunchDataType): ToolConfigType { - const mappedType = toolLaunchDataTypeToToolConfigTypeMapping[launchDataType]; return mappedType; } static mapToToolLaunchRequestResponse(toolLaunchRequest: ToolLaunchRequest): ToolLaunchRequestResponse { - const { method, url, payload, openNewTab, isDeepLink } = toolLaunchRequest; - - const response = new ToolLaunchRequestResponse({ - method, - url, - payload, - openNewTab, - isDeepLink, - }); + const response = new ToolLaunchRequestResponse(toolLaunchRequest); + return response; } } diff --git a/apps/server/src/modules/tool/tool-launch/service/launch-strategy/lti11-tool-launch.strategy.ts b/apps/server/src/modules/tool/tool-launch/service/launch-strategy/lti11-tool-launch.strategy.ts index 6b2554acada..21e05771640 100644 --- a/apps/server/src/modules/tool/tool-launch/service/launch-strategy/lti11-tool-launch.strategy.ts +++ b/apps/server/src/modules/tool/tool-launch/service/launch-strategy/lti11-tool-launch.strategy.ts @@ -3,8 +3,6 @@ import { DefaultEncryptionService, EncryptionService } from '@infra/encryption'; import { ObjectId } from '@mikro-orm/mongodb'; import { PseudonymService } from '@modules/pseudonym/service'; import { UserService } from '@modules/user'; -import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { Cache } from 'cache-manager'; import { Inject, Injectable, InternalServerErrorException, UnprocessableEntityException } from '@nestjs/common'; import { Pseudonym, RoleReference, UserDO } from '@shared/domain/domainobject'; import { RoleName } from '@shared/domain/interface'; @@ -24,10 +22,10 @@ import { import { AutoContextIdStrategy, AutoContextNameStrategy, + AutoGroupExternalUuidStrategy, AutoMediumIdStrategy, AutoSchoolIdStrategy, AutoSchoolNumberStrategy, - AutoGroupExternalUuidStrategy, } from '../auto-parameter-strategy'; import { Lti11EncryptionService } from '../lti11-encryption.service'; import { AbstractLaunchStrategy } from './abstract-launch.strategy'; @@ -40,7 +38,6 @@ export class Lti11ToolLaunchStrategy extends AbstractLaunchStrategy { private readonly pseudonymService: PseudonymService, private readonly lti11EncryptionService: Lti11EncryptionService, @Inject(DefaultEncryptionService) private readonly encryptionService: EncryptionService, - @Inject(CACHE_MANAGER) private readonly cacheManager: Cache, autoSchoolIdStrategy: AutoSchoolIdStrategy, autoSchoolNumberStrategy: AutoSchoolNumberStrategy, autoContextIdStrategy: AutoContextIdStrategy, @@ -72,10 +69,7 @@ export class Lti11ToolLaunchStrategy extends AbstractLaunchStrategy { } let properties: PropertyData[]; - if ( - config.lti_message_type === LtiMessageType.CONTENT_ITEM_SELECTION_REQUEST && - !data.contextExternalTool.ltiDeepLink - ) { + if (config.lti_message_type === LtiMessageType.CONTENT_ITEM_SELECTION_REQUEST) { properties = await this.buildToolLaunchDataForContentItemSelectionRequest(userId, data, config); } else { properties = await this.buildToolLaunchDataForLtiLaunch( @@ -105,16 +99,15 @@ export class Lti11ToolLaunchStrategy extends AbstractLaunchStrategy { LtiMessageType.CONTENT_ITEM_SELECTION_REQUEST ); - const publicBackendUrl = Configuration.get('PUBLIC_BACKEND_URL') as string; - const callbackUrl = `${publicBackendUrl}/v3/tools/context-external-tools/${data.contextExternalTool.id}/lti11-deep-link-callback`; + const clientUrl = Configuration.get('HOST') as string; + const callbackUrl = new URL('/dashboard', clientUrl); const state = new UUID().toString(); - await this.cacheManager.set(state, userId, 600000); additionalProperties.push( new PropertyData({ name: 'content_item_return_url', - value: callbackUrl, + value: callbackUrl.toString(), location: PropertyLocation.BODY, }), new PropertyData({ @@ -308,8 +301,7 @@ export class Lti11ToolLaunchStrategy extends AbstractLaunchStrategy { if ( ExternalTool.isLti11Config(data.externalTool.config) && - data.externalTool.config.lti_message_type === LtiMessageType.CONTENT_ITEM_SELECTION_REQUEST && - !data.contextExternalTool.ltiDeepLink + data.externalTool.config.lti_message_type === LtiMessageType.CONTENT_ITEM_SELECTION_REQUEST ) { request.openNewTab = true; request.isDeepLink = true; diff --git a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts index d108900ad4e..09e93d160c5 100644 --- a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts +++ b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts @@ -56,6 +56,7 @@ export class ToolLaunchService { schoolExternalTool, contextExternalTool, }); + return launchRequest; } diff --git a/apps/server/src/modules/tool/tool-launch/tool-launch.module.ts b/apps/server/src/modules/tool/tool-launch/tool-launch.module.ts index 102b153341c..d58f0ad2cca 100644 --- a/apps/server/src/modules/tool/tool-launch/tool-launch.module.ts +++ b/apps/server/src/modules/tool/tool-launch/tool-launch.module.ts @@ -1,11 +1,10 @@ import { EncryptionModule } from '@infra/encryption'; -import { CacheWrapperModule } from '@infra/cache'; import { BoardModule } from '@modules/board'; +import { GroupModule } from '@modules/group'; import { LearnroomModule } from '@modules/learnroom'; import { LegacySchoolModule } from '@modules/legacy-school'; import { PseudonymModule } from '@modules/pseudonym'; import { UserModule } from '@modules/user'; -import { GroupModule } from '@modules/group'; import { forwardRef, Module } from '@nestjs/common'; import { CommonToolModule } from '../common'; import { ContextExternalToolModule } from '../context-external-tool'; @@ -15,10 +14,10 @@ import { Lti11EncryptionService, ToolLaunchService } from './service'; import { AutoContextIdStrategy, AutoContextNameStrategy, + AutoGroupExternalUuidStrategy, AutoMediumIdStrategy, AutoSchoolIdStrategy, AutoSchoolNumberStrategy, - AutoGroupExternalUuidStrategy, } from './service/auto-parameter-strategy'; import { BasicToolLaunchStrategy, Lti11ToolLaunchStrategy, OAuth2ToolLaunchStrategy } from './service/launch-strategy'; @@ -35,7 +34,6 @@ import { BasicToolLaunchStrategy, Lti11ToolLaunchStrategy, OAuth2ToolLaunchStrat BoardModule, GroupModule, EncryptionModule, - CacheWrapperModule, ], providers: [ ToolLaunchService, diff --git a/apps/server/src/modules/tool/tool-launch/types/tool-launch-request.ts b/apps/server/src/modules/tool/tool-launch/types/tool-launch-request.ts index b4ebaac4957..9b7d34a130d 100644 --- a/apps/server/src/modules/tool/tool-launch/types/tool-launch-request.ts +++ b/apps/server/src/modules/tool/tool-launch/types/tool-launch-request.ts @@ -16,6 +16,6 @@ export class ToolLaunchRequest { this.method = props.method; this.payload = props.payload; this.openNewTab = props.openNewTab; - this.isDeepLink = props.openNewTab; + this.isDeepLink = props.isDeepLink; } } diff --git a/apps/server/src/modules/user/service/user.service.spec.ts b/apps/server/src/modules/user/service/user.service.spec.ts index ad5986d259d..9cc8efd2ede 100644 --- a/apps/server/src/modules/user/service/user.service.spec.ts +++ b/apps/server/src/modules/user/service/user.service.spec.ts @@ -1,9 +1,7 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; -import { ICurrentUser } from '@infra/auth-guard'; import { CalendarService } from '@infra/calendar'; import { EntityManager, MikroORM } from '@mikro-orm/core'; import { ObjectId } from '@mikro-orm/mongodb'; -import { Account, AccountService } from '@modules/account'; import { DataDeletedEvent, DeletionErrorLoggableException, @@ -41,7 +39,6 @@ describe('UserService', () => { let userDORepo: DeepMocked; let config: DeepMocked; let roleService: DeepMocked; - let accountService: DeepMocked; let registrationPinService: DeepMocked; let calendarService: DeepMocked; let eventBus: DeepMocked; @@ -72,10 +69,6 @@ describe('UserService', () => { provide: RoleService, useValue: createMock(), }, - { - provide: AccountService, - useValue: createMock(), - }, { provide: RegistrationPinService, useValue: createMock(), @@ -106,7 +99,6 @@ describe('UserService', () => { userDORepo = module.get(UserDORepo); config = module.get(ConfigService); roleService = module.get(RoleService); - accountService = module.get(AccountService); registrationPinService = module.get(RegistrationPinService); eventBus = module.get(EventBus); calendarService = module.get(CalendarService); @@ -261,54 +253,6 @@ describe('UserService', () => { }); }); - describe('getResolvedUser is called', () => { - describe('when a resolved user is requested', () => { - const setup = () => { - const systemId = 'systemId'; - const role: Role = roleFactory.buildWithId({ - name: RoleName.STUDENT, - permissions: [Permission.DASHBOARD_VIEW], - }); - const user: UserDO = userDoFactory.buildWithId({ roles: [role] }); - const account: Account = new Account({ - id: 'accountId', - systemId, - username: 'username', - createdAt: new Date(), - updatedAt: new Date(), - activated: true, - }); - - userDORepo.findById.mockResolvedValue(user); - accountService.findByUserIdOrFail.mockResolvedValue(account); - - return { - userId: user.id as string, - user, - account, - role, - systemId, - }; - }; - - it('should return the current user', async () => { - const { userId, user, account, role, systemId } = setup(); - - const result = await service.getResolvedUser(userId); - - expect(result).toEqual({ - userId, - systemId, - schoolId: user.schoolId, - accountId: account.id, - roles: [role.id], - isExternalUser: false, - support: false, - }); - }); - }); - }); - describe('getDisplayName', () => { let role: Role; @@ -946,7 +890,7 @@ describe('UserService', () => { }); }); - describe('findByExternalIdsAndProvidedBySystemId', () => { + describe('findMultipleByExternalIds', () => { const setup = () => { const systemId = new ObjectId().toHexString(); const userA = userFactory.buildWithId({ externalId: '111' }); @@ -962,39 +906,27 @@ describe('UserService', () => { }; }; - describe('when find users By externalIds and systemId', () => { - it('should call findMultipleByExternalIds in userService with externalIds', async () => { - const { externalIds, foundUsers, systemId } = setup(); - - jest.spyOn(service, 'findMultipleByExternalIds').mockResolvedValueOnce(foundUsers); + it('should call findMultipleByExternalIds in userService with externalIds', async () => { + const { externalIds, foundUsers } = setup(); - await service.findByExternalIdsAndProvidedBySystemId(externalIds, systemId); - - expect(service.findMultipleByExternalIds).toHaveBeenCalledWith(externalIds); - }); + userRepo.findByExternalIds.mockResolvedValueOnce(foundUsers); - it('should call accountService.findByUserIdsAndSystemId with foundUsers and systemId', async () => { - const { externalIds, foundUsers, systemId } = setup(); + await service.findMultipleByExternalIds(externalIds); - jest.spyOn(service, 'findMultipleByExternalIds').mockResolvedValueOnce(foundUsers); - - await service.findByExternalIdsAndProvidedBySystemId(externalIds, systemId); - - expect(accountService.findByUserIdsAndSystemId).toHaveBeenCalledWith(foundUsers, systemId); - }); + expect(userRepo.findByExternalIds).toHaveBeenCalledWith(externalIds); + }); - it('should return array with verified Users', async () => { - const { externalIds, foundUsers, systemId } = setup(); + it('should return array with verified Users', async () => { + const { externalIds, foundUsers } = setup(); - jest.spyOn(service, 'findMultipleByExternalIds').mockResolvedValueOnce(foundUsers); - jest.spyOn(accountService, 'findByUserIdsAndSystemId').mockResolvedValueOnce(foundUsers); + userRepo.findByExternalIds.mockResolvedValueOnce(foundUsers); - const result = await service.findByExternalIdsAndProvidedBySystemId(externalIds, systemId); + const result = await service.findMultipleByExternalIds(externalIds); - expect(result).toEqual(foundUsers); - }); + expect(result).toEqual(foundUsers); }); }); + describe('findUnsynchronizedUserIds', () => { const setup = () => { const currentDate = new Date(); diff --git a/apps/server/src/modules/user/service/user.service.ts b/apps/server/src/modules/user/service/user.service.ts index 2e788707300..4546dcb9226 100644 --- a/apps/server/src/modules/user/service/user.service.ts +++ b/apps/server/src/modules/user/service/user.service.ts @@ -1,8 +1,4 @@ import { MikroORM, UseRequestContext } from '@mikro-orm/core'; -import { Account, AccountService } from '@modules/account'; -// invalid import -import { OauthCurrentUser } from '@modules/authentication/interface'; -import { CurrentUserMapper } from '@modules/authentication/mapper'; import { DataDeletedEvent, DataDeletionDomainOperationLoggable, @@ -44,7 +40,6 @@ export class UserService implements DeletionService, IEventHandler, private readonly roleService: RoleService, - private readonly accountService: AccountService, private readonly registrationPinService: RegistrationPinService, private readonly calendarService: CalendarService, private readonly logger: Logger, @@ -84,15 +79,6 @@ export class UserService implements DeletionService, IEventHandler { - const user: UserDO = await this.findById(userId); - const account: Account = await this.accountService.findByUserIdOrFail(userId); - - const resolvedUser: OauthCurrentUser = CurrentUserMapper.mapToOauthCurrentUser(account.id, user, account.systemId); - - return resolvedUser; - } - async findById(id: string): Promise { const userDO = await this.userDORepo.findById(id, true); @@ -261,14 +247,6 @@ export class UserService implements DeletionService, IEventHandler { - const foundUsers = await this.findMultipleByExternalIds(externalIds); - - const verifiedUsers = await this.accountService.findByUserIdsAndSystemId(foundUsers, systemId); - - return verifiedUsers; - } - public async findMultipleByExternalIds(externalIds: string[]): Promise { return this.userRepo.findByExternalIds(externalIds); } diff --git a/apps/server/src/modules/user/user.module.ts b/apps/server/src/modules/user/user.module.ts index 501226c6d5f..10f0d678834 100644 --- a/apps/server/src/modules/user/user.module.ts +++ b/apps/server/src/modules/user/user.module.ts @@ -1,25 +1,15 @@ -import { AccountModule } from '@modules/account'; -import { LegacySchoolModule } from '@modules/legacy-school'; +import { CalendarModule } from '@infra/calendar'; +import { RegistrationPinModule } from '@modules/registration-pin'; import { RoleModule } from '@modules/role'; -import { forwardRef, Module } from '@nestjs/common'; +import { Module } from '@nestjs/common'; +import { CqrsModule } from '@nestjs/cqrs'; import { UserRepo } from '@shared/repo'; import { UserDORepo } from '@shared/repo/user/user-do.repo'; import { LoggerModule } from '@src/core/logger'; -import { CqrsModule } from '@nestjs/cqrs'; -import { RegistrationPinModule } from '@modules/registration-pin'; -import { CalendarModule } from '@infra/calendar'; import { UserService } from './service'; @Module({ - imports: [ - forwardRef(() => LegacySchoolModule), - RoleModule, - AccountModule, - LoggerModule, - CqrsModule, - RegistrationPinModule, - CalendarModule, - ], + imports: [RoleModule, LoggerModule, CqrsModule, RegistrationPinModule, CalendarModule], providers: [UserRepo, UserDORepo, UserService], exports: [UserService, UserRepo], }) diff --git a/apps/server/src/shared/controller/transformer/string-to-json.transformer.ts b/apps/server/src/shared/controller/transformer/string-to-json.transformer.ts deleted file mode 100644 index 6edb5f1f673..00000000000 --- a/apps/server/src/shared/controller/transformer/string-to-json.transformer.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { plainToClass, Transform, TransformFnParams } from 'class-transformer'; -import { ClassConstructor } from 'class-transformer/types/interfaces'; - -export function StringToObject(classType: ClassConstructor): PropertyDecorator { - return Transform((params: TransformFnParams) => { - if (typeof params.value === 'string') { - const res: unknown = JSON.parse(params.value); - - const obj: unknown = plainToClass(classType, res, params.options); - - return obj; - } - - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return params.value; - }); -} diff --git a/backup/setup/external-tools.json b/backup/setup/external-tools.json index abe5a676c86..f2a1c02bf38 100644 --- a/backup/setup/external-tools.json +++ b/backup/setup/external-tools.json @@ -1101,6 +1101,7 @@ "isPreferred": true, "iconName": "mdiEyeOutline" }, + { "_id": { "$oid":"667e52a4162707ce02b9ac05" @@ -1125,5 +1126,30 @@ "openNewTab":false, "restrictToContexts":[], "isPreferred":true + }, + { + "_id": { + "$oid": "667e52a4162707ce02b9ac06" + }, + "createdAt": { + "$date": "2024-10-25T02:16:42.959Z" + }, + "updatedAt": { + "$date": "2024-10-25T02:16:42.959Z" + }, + "name": "Merlin Bibliothek", + "url": "https://nds.edupool.de", + "config_type": "lti11", + "config_baseUrl": "https://nds.edupool.de", + "config_key": "xvD0eMHxEPsKI198", + "config_lti_message_type": "ContentItemSelectionRequest", + "config_privacy_permission": "anonymous", + "config_launch_presentation_locale": "de-DE", + "parameters": [], + "isHidden": false, + "isDeactivated": false, + "openNewTab": false, + "restrictToContexts": [], + "isPreferred": true } ] diff --git a/redeploy b/redeploy deleted file mode 100644 index 56a6051ca2b..00000000000 --- a/redeploy +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/sonar-project.properties b/sonar-project.properties index d8f2f98ccd8..0501516afc7 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,7 +3,7 @@ sonar.projectKey=hpi-schul-cloud_schulcloud-server sonar.sources=. sonar.tests=. sonar.test.inclusions=**/*.spec.ts -sonar.exclusions=**/*.js,jest.config.ts,globalSetup.ts,globalTeardown.ts,**/*.app.ts,**/seed-data/*.ts,**/migrations/mikro-orm/*.ts,**/etherpad-api-client/**/*.ts,**/authorization-api-client/**/*.ts, **/course-api-client/**/*.ts,**/board-api-client/**/*.ts,**/generated/**/*.ts,**/room-api-client/**/*.ts,**/lessons-api-client/**/*.ts +sonar.exclusions=**/*.js,jest.config.ts,globalSetup.ts,globalTeardown.ts,**/*.app.ts,**/seed-data/*.ts,**/migrations/mikro-orm/*.ts,**/etherpad-api-client/**/*.ts,**/authorization-api-client/**/*.ts, **/course-api-client/**/*.ts,**/board-api-client/**/*.ts,**/generated/**/*.ts,**/room-api-client/**/*.ts,**/cards-api-client/**/*.ts,**/lessons-api-client/**/*.ts sonar.coverage.exclusions=**/board-management.uc.ts,**/*.module.ts,**/*.factory.ts,**/migrations/mikro-orm/*.ts,**/globalSetup.ts,**/globalTeardown.ts,**/etherpad-api-client/**/*.ts,**/authorization-api-client/**/*.ts, **/course-api-client/**/*.ts,**/board-api-client/**/*.ts,**/generated/**/*.ts,**/room-api-client/**/*.ts sonar.cpd.exclusions=**/controller/dto/**/*.ts,**/api/dto/**/*.ts,**/shared/testing/factory/*.factory.ts sonar.javascript.lcov.reportPaths=merged-lcov.info