From b867ef97a0fa4a9d3ce0905e683a29444d569917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Cutzach?= Date: Tue, 29 Oct 2024 16:21:36 +0100 Subject: [PATCH 1/7] feat: creating tests layout --- test/gen-server/ApiServer.ts | 98 ++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/test/gen-server/ApiServer.ts b/test/gen-server/ApiServer.ts index e9928e0950..3d03a0a7f8 100644 --- a/test/gen-server/ApiServer.ts +++ b/test/gen-server/ApiServer.ts @@ -2351,6 +2351,104 @@ describe('ApiServer', function() { // Assert that the response status is 404 because the templates org doesn't exist. assert.equal(resp.status, 404); }); + + describe('Service Accounts', function() { + let oldEnv: testUtils.EnvironmentSnapshot; + + testUtils.setTmpLogLevel('error'); + + before(async function() { + oldEnv = new testUtils.EnvironmentSnapshot(); + process.env.GRIST_TEMPLATE_ORG = 'templates'; + server = new TestServer(this); + homeUrl = await server.start(['home', 'docs']); + dbManager = server.dbManager; + + chimpyRef = await dbManager.getUserByLogin(chimpyEmail).then((user) => user.ref); + kiwiRef = await dbManager.getUserByLogin(kiwiEmail).then((user) => user.ref); + charonRef = await dbManager.getUserByLogin(charonEmail).then((user) => user.ref); + + // Listen to user count updates and add them to an array. + dbManager.on('userChange', ({org, countBefore, countAfter}: UserChange) => { + if (countBefore === countAfter) { return; } + userCountUpdates[org.id] = userCountUpdates[org.id] || []; + userCountUpdates[org.id].push(countAfter); + }); + }); + + afterEach(async function() { + oldEnv.restore(); + // FIXME create the new method to delete services accounts + //const did = await dbManager.testGetId('Curiosity'); + // await dbManager.deleteServices(did as string); + }); + + after(async function() { + await server.stop(); + }); + + it('Endpoint POST /api/service-accounts is operational', async function() { + + }); + + it('Endpoint POST /api/service-accounts returns 400 when missing parameter in request body', async function() { + + }); + + it('Endpoint POST /api/service-accounts returns 400 on invalid endOfLife', async function() { + + }); + + it('Endpoint GET /api/service-accounts is operational', async function() { + + }); + + it("Endpoint GET /api/service-accounts returns 404 when user don't own any service account", async function() { + + }); + + it('Endpoint GET /api/service-accounts/{saId} is operational', async function() { + + }); + + it('Endpoint GET /api/service-accounts/{saId} returns 404 on non-existing {saId}', async function() { + + }); + + it('Endpoint UPDATE /api/service-accounts/{saId} is operational', async function() { + + }); + + it('Endpoint UPDATE /api/service-accounts/{saId} returns 404 on non-existing {saId}', async function() { + + }); + + it('Endpoint UPDATE /api/service-accounts/{saId} returns 400 on empty label', async function() { + + }); + + // What are we doing about empty description ? + + it('Endpoint UPDATE /api/service-accounts/{saId} returns 400 on invalid endOfLife', async function() { + + }); + + it('Endpoint UPDATE /api/service-accounts/{saId} returns 400 if trying to update owner', async function() { + + }); + + it('Endpoint DELETE /api/service-accounts/{saId} is operational', async function() { + + }); + + it('Endpoint DELETE /api/service-accounts/{saId} returns 404 on non-existing {saId}', async function() { + + }); + + // it('Endpoint UPDATE /api/service-accounts/{saId}/transfer-to/{userId}', async function() { + + // }); + }); }); From cb768da561a5da8cdf61413de5cea3bcd10a1e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Cutzach?= Date: Tue, 29 Oct 2024 17:55:39 +0100 Subject: [PATCH 2/7] feat: ADD Service Accounts DB migration --- .../1730215435023-ServiceAccounts.ts | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 app/gen-server/migration/1730215435023-ServiceAccounts.ts diff --git a/app/gen-server/migration/1730215435023-ServiceAccounts.ts b/app/gen-server/migration/1730215435023-ServiceAccounts.ts new file mode 100644 index 0000000000..b2f1a9fdae --- /dev/null +++ b/app/gen-server/migration/1730215435023-ServiceAccounts.ts @@ -0,0 +1,80 @@ +import { MigrationInterface, QueryRunner, Table, TableColumn, TableForeignKey, TableIndex } from "typeorm"; + +export class ServiceAccounts1730215435023 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumn('users', new TableColumn({ + name: 'type', + type: 'varchar', + isNullable: false, + default: "'login'", + })); + await queryRunner.createTable( + new Table({ + name: 'service_accounts', + columns: [ + { + name: 'id', + type: 'int', + isPrimary: true, + }, + { + name: 'description', + type: 'varchar' + }, + { + name: 'endOfLife', + type: 'date', + default: 'now()', + }, + ], + }) + ); + await queryRunner.createTable( + new Table({ + name: 'service_account_user', + columns: [ + { + name: 'service_account_id', + type: 'int', + }, + { + name: 'user_id', + type: 'int' + }, + ], + }) + ); + await queryRunner.createForeignKey( + 'service_account_user', + new TableForeignKey({ + columnNames: ['service_account_id'], + referencedColumnNames: ['id'], + referencedTableName: 'service_accounts', + onDelete: 'CASCADE', + }) + ); + await queryRunner.createForeignKey( + 'service_account_user', + new TableForeignKey({ + columnNames: ['user_id'], + referencedColumnNames: ['id'], + referencedTableName: 'users', + onDelete: 'CASCADE', + }) + ); + await queryRunner.createIndex( + 'service_account_user', + new TableIndex({ + name: 'service_account__user', + columnNames: ['service_account_id', 'user_id'], + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('users', 'type'); + await queryRunner.dropTable('service_accounts'); + await queryRunner.dropTable('service_account_user'); + } +} From 1eabc11ce9b70795cf46cbd88e92a4f12945d633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Cutzach?= Date: Wed, 30 Oct 2024 10:22:54 +0100 Subject: [PATCH 3/7] chore: ADD Service accounts migration tests --- test/gen-server/migrations.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/gen-server/migrations.ts b/test/gen-server/migrations.ts index 2795fd2529..cf549d247e 100644 --- a/test/gen-server/migrations.ts +++ b/test/gen-server/migrations.ts @@ -49,6 +49,7 @@ import {ActivationEnabled1722529827161 import {Configs1727747249153 as Configs} from 'app/gen-server/migration/1727747249153-Configs'; import {LoginsEmailsIndex1729754662550 as LoginsEmailsIndex} from 'app/gen-server/migration/1729754662550-LoginsEmailIndex'; +import {ServiceAccounts1730215435023 as ServiceAccounts} from 'app/gen-server/migration/1730215435023-ServiceAccounts'; const home: HomeDBManager = new HomeDBManager(); @@ -58,7 +59,7 @@ const migrations = [Initial, Login, PinDocs, UserPicture, DisplayEmail, DisplayE ExternalBilling, DocOptions, Secret, UserOptions, GracePeriodStart, DocumentUsage, Activations, UserConnectId, UserUUID, UserUniqueRefUUID, Forks, ForkIndexes, ActivationPrefs, AssistantLimit, Shares, BillingFeatures, - UserLastConnection, ActivationEnabled, Configs, LoginsEmailsIndex]; + UserLastConnection, ActivationEnabled, Configs, LoginsEmailsIndex, ServiceAccounts]; // Assert that the "members" acl rule and group exist (or not). function assertMembersGroup(org: Organization, exists: boolean) { From a5130a1f0c83ff29a199dc805cf12c3fcffd83e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Cutzach?= Date: Wed, 30 Oct 2024 10:52:20 +0100 Subject: [PATCH 4/7] feat: add column type to User Entity --- app/common/User.ts | 10 ++++++++++ app/gen-server/entity/User.ts | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/app/common/User.ts b/app/common/User.ts index 4e3419a148..36d0127c9c 100644 --- a/app/common/User.ts +++ b/app/common/User.ts @@ -2,6 +2,14 @@ import {getTableId} from 'app/common/DocActions'; import {EmptyRecordView, RecordView} from 'app/common/RecordView'; import {Role} from 'app/common/roles'; +/** + * User type to distinguish beetween Users and service accounts + */ +export enum UserTypes { + 'login', + 'service' +} + /** * Information about a user, including any user attributes. */ @@ -19,6 +27,7 @@ export interface UserInfo { * via a share. Otherwise null. */ ShareRef: number | null; + Type: UserTypes | null; [attributes: string]: unknown; } @@ -37,6 +46,7 @@ export class User implements UserInfo { public SessionID: string | null = null; public UserRef: string | null = null; public ShareRef: number | null = null; + public Type: UserTypes | null = null; [attribute: string]: any; constructor(info: Record = {}) { diff --git a/app/gen-server/entity/User.ts b/app/gen-server/entity/User.ts index b4a9909033..46fb54f5e0 100644 --- a/app/gen-server/entity/User.ts +++ b/app/gen-server/entity/User.ts @@ -1,4 +1,5 @@ import {UserOptions} from 'app/common/UserAPI'; +import {UserTypes} from 'app/common/User'; import {nativeValues} from 'app/gen-server/lib/values'; import {makeId} from 'app/server/lib/idUtils'; import {BaseEntity, BeforeInsert, Column, Entity, JoinTable, ManyToMany, OneToMany, OneToOne, @@ -64,6 +65,9 @@ export class User extends BaseEntity { @Column({name: 'ref', type: String, nullable: false}) public ref: string; + @Column({name: 'type', type: String, default: 'login'}) + public type: UserTypes | null; + @BeforeInsert() public async beforeInsert() { if (!this.ref) { From 35386e87920b8f551c8482ddd9d7f79f8a59e4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Cutzach?= Date: Tue, 19 Nov 2024 16:29:18 +0100 Subject: [PATCH 5/7] feat: create new entity Service Account creating a join table with users and modify Users accordingly\n add a type column to user table --- app/gen-server/entity/ServiceAccount.ts | 24 ++++++++++++++++++++++++ app/gen-server/entity/User.ts | 8 ++++++++ 2 files changed, 32 insertions(+) create mode 100644 app/gen-server/entity/ServiceAccount.ts diff --git a/app/gen-server/entity/ServiceAccount.ts b/app/gen-server/entity/ServiceAccount.ts new file mode 100644 index 0000000000..daf07cc64e --- /dev/null +++ b/app/gen-server/entity/ServiceAccount.ts @@ -0,0 +1,24 @@ +import {BaseEntity, Column, Entity, JoinTable, ManyToOne, PrimaryGeneratedColumn} from "typeorm"; +import { User } from './User'; + +@Entity({name: 'service_accounts'}) +export class ServiceAccount extends BaseEntity { + + @PrimaryGeneratedColumn() + public id: number; + + + @Column({type: String}) + public description: string; + + @Column({type: Date, default: Date.now()}) + public endOfLife: string; + + @ManyToOne(type => User) + @JoinTable({ + name: 'service_account_user', + joinColumn: {name: 'service_account_id'}, + inverseJoinColumn: {name: 'user_id'} + }) + public service_account_owner: User; +} diff --git a/app/gen-server/entity/User.ts b/app/gen-server/entity/User.ts index 46fb54f5e0..3f1110c4bb 100644 --- a/app/gen-server/entity/User.ts +++ b/app/gen-server/entity/User.ts @@ -9,6 +9,7 @@ import {Group} from "./Group"; import {Login} from "./Login"; import {Organization} from "./Organization"; import {Pref} from './Pref'; +import {ServiceAccount} from './ServiceAccount'; @Entity({name: 'users'}) export class User extends BaseEntity { @@ -59,6 +60,13 @@ export class User extends BaseEntity { @Column({name: 'connect_id', type: String, nullable: true}) public connectId: string | null; + @OneToMany(type => User, user => user.serviceAccounts) + @JoinTable({ + name: 'service_account_user', + joinColumn: {name: 'user_id'}, + inverseJoinColumn: {name: 'service_account_id'} + }) + public serviceAccounts: ServiceAccount[]; /** * Unique reference for this user. Primarily used as an ownership key in a cell metadata (comments). */ From 8b32d17aab706ce1e7e29dd045d1d74ea2d1d7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Cutzach?= Date: Wed, 20 Nov 2024 10:28:08 +0100 Subject: [PATCH 6/7] fix: change date type to avoid migration silent failure --- app/gen-server/entity/ServiceAccount.ts | 3 +-- app/gen-server/migration/1730215435023-ServiceAccounts.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/gen-server/entity/ServiceAccount.ts b/app/gen-server/entity/ServiceAccount.ts index daf07cc64e..db57aab5e3 100644 --- a/app/gen-server/entity/ServiceAccount.ts +++ b/app/gen-server/entity/ServiceAccount.ts @@ -7,11 +7,10 @@ export class ServiceAccount extends BaseEntity { @PrimaryGeneratedColumn() public id: number; - @Column({type: String}) public description: string; - @Column({type: Date, default: Date.now()}) + @Column({type: Date, nullable: false}) public endOfLife: string; @ManyToOne(type => User) diff --git a/app/gen-server/migration/1730215435023-ServiceAccounts.ts b/app/gen-server/migration/1730215435023-ServiceAccounts.ts index b2f1a9fdae..5b217365a1 100644 --- a/app/gen-server/migration/1730215435023-ServiceAccounts.ts +++ b/app/gen-server/migration/1730215435023-ServiceAccounts.ts @@ -1,8 +1,12 @@ import { MigrationInterface, QueryRunner, Table, TableColumn, TableForeignKey, TableIndex } from "typeorm"; +import * as sqlUtils from "app/gen-server/sqlUtils"; export class ServiceAccounts1730215435023 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { + const dbType = queryRunner.connection.driver.options.type; + const datetime = sqlUtils.datetime(dbType); + await queryRunner.addColumn('users', new TableColumn({ name: 'type', type: 'varchar', @@ -24,8 +28,8 @@ export class ServiceAccounts1730215435023 implements MigrationInterface { }, { name: 'endOfLife', - type: 'date', - default: 'now()', + type: datetime, + isNullable: false, }, ], }) From f60f396927223d488ad66f6edc682793ced7cb2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Cutzach?= Date: Mon, 25 Nov 2024 09:42:18 +0100 Subject: [PATCH 7/7] chore: Rebase --- app/common/User.ts | 2 + app/gen-server/ApiServer.ts | 29 ++++++++++ app/gen-server/entity/ServiceAccount.ts | 17 +++--- app/gen-server/entity/User.ts | 4 +- app/gen-server/lib/homedb/HomeDBManager.ts | 14 +++++ .../lib/homedb/ServiceAccountsManager.ts | 55 +++++++++++++++++++ app/gen-server/lib/homedb/UsersManager.ts | 6 +- .../1730215435023-ServiceAccounts.ts | 42 ++++++-------- test/gen-server/ApiServer.ts | 8 ++- 9 files changed, 136 insertions(+), 41 deletions(-) create mode 100644 app/gen-server/lib/homedb/ServiceAccountsManager.ts diff --git a/app/common/User.ts b/app/common/User.ts index 36d0127c9c..f7eff6b32e 100644 --- a/app/common/User.ts +++ b/app/common/User.ts @@ -10,6 +10,8 @@ export enum UserTypes { 'service' } +export type UserTypesStrings = keyof typeof UserTypes; + /** * Information about a user, including any user attributes. */ diff --git a/app/gen-server/ApiServer.ts b/app/gen-server/ApiServer.ts index 192bb8ed63..616c2cf69d 100644 --- a/app/gen-server/ApiServer.ts +++ b/app/gen-server/ApiServer.ts @@ -599,6 +599,35 @@ export class ApiServer { if (data) { this._logDeleteUserEvents(req, data); } return sendReply(req, res, result); })); + + // POST /service-accounts/ + // Creates a new service account attached to the user making the api call. + this._app.post('/api/service-accounts', expressWrap(async (req, res) => { + const userId = getAuthorizedUserId(req); + const serviceAccount: any = await this._dbManager.createServiceAccount(req.body); + return sendOkReply(req, res, { + key:serviceAccount.key, + }); + throw new ApiError(`${userId} post Not implemented yet ;)`, 501); + })); + + // GET /service-accounts/ + // Reads all service accounts attached to the user making the api call. + this._app.get('/api/service-accounts', expressWrap(async (req, res) => { + throw new ApiError('get Not implemented yet ;)', 501); + })); + + // GET /service-accounts/:said + // Reads one particular service account of the user making the api call. + this._app.get('/api/service-accounts/:said', expressWrap(async (req, res) => { + throw new ApiError('get by id Not implemented yet ;)', 501); + })); + + // DELETE /service-accounts/:said + // Deletes one particular service account of the user making the api call. + this._app.delete('/api/service-accounts/:said', expressWrap(async (req, res) => { + throw new ApiError('delete by id Not implemented yet ;)', 501); + })); } private async _getFullUser(req: Request, options: {includePrefs?: boolean} = {}): Promise { diff --git a/app/gen-server/entity/ServiceAccount.ts b/app/gen-server/entity/ServiceAccount.ts index db57aab5e3..0a687822f6 100644 --- a/app/gen-server/entity/ServiceAccount.ts +++ b/app/gen-server/entity/ServiceAccount.ts @@ -1,5 +1,4 @@ -import {BaseEntity, Column, Entity, JoinTable, ManyToOne, PrimaryGeneratedColumn} from "typeorm"; -import { User } from './User'; +import {BaseEntity, Column, Entity, PrimaryGeneratedColumn} from "typeorm"; @Entity({name: 'service_accounts'}) export class ServiceAccount extends BaseEntity { @@ -7,17 +6,15 @@ export class ServiceAccount extends BaseEntity { @PrimaryGeneratedColumn() public id: number; + @Column({type: Number}) + public owner_id: number; + + @Column({type: Number}) + public service_user_id: number; + @Column({type: String}) public description: string; @Column({type: Date, nullable: false}) public endOfLife: string; - - @ManyToOne(type => User) - @JoinTable({ - name: 'service_account_user', - joinColumn: {name: 'service_account_id'}, - inverseJoinColumn: {name: 'user_id'} - }) - public service_account_owner: User; } diff --git a/app/gen-server/entity/User.ts b/app/gen-server/entity/User.ts index 3f1110c4bb..cf2dc21b9d 100644 --- a/app/gen-server/entity/User.ts +++ b/app/gen-server/entity/User.ts @@ -1,5 +1,5 @@ import {UserOptions} from 'app/common/UserAPI'; -import {UserTypes} from 'app/common/User'; +import {UserTypesStrings} from 'app/common/User'; import {nativeValues} from 'app/gen-server/lib/values'; import {makeId} from 'app/server/lib/idUtils'; import {BaseEntity, BeforeInsert, Column, Entity, JoinTable, ManyToMany, OneToMany, OneToOne, @@ -74,7 +74,7 @@ export class User extends BaseEntity { public ref: string; @Column({name: 'type', type: String, default: 'login'}) - public type: UserTypes | null; + public type: UserTypesStrings | null; @BeforeInsert() public async beforeInsert() { diff --git a/app/gen-server/lib/homedb/HomeDBManager.ts b/app/gen-server/lib/homedb/HomeDBManager.ts index d4593ebda4..20b36280cd 100644 --- a/app/gen-server/lib/homedb/HomeDBManager.ts +++ b/app/gen-server/lib/homedb/HomeDBManager.ts @@ -89,6 +89,7 @@ import { } from "typeorm"; import {v4 as uuidv4} from "uuid"; import { GroupsManager } from './GroupsManager'; +import { ServiceAccountsManager } from './ServiceAccountsManager'; // Support transactions in Sqlite in async code. This is a monkey patch, affecting // the prototypes of various TypeORM classes. @@ -254,6 +255,7 @@ export type BillingOptions = Partial { + //TODO create new service user in order to have its + //id to insert + const uuid = uuidv4(); + const email = `${uuid}@serviceaccounts.local`; + const serviceUser = await this._homeDb.getUserByLogin(email); + // FIXME use manager.save(entité); + return await manager.createQueryBuilder() + .insert() + .into('service_accounts') + .values({ + ownerId, + serviceUserId: serviceUser.id, + description, + endOfLife, + }) + .execute(); + }); + } +} diff --git a/app/gen-server/lib/homedb/UsersManager.ts b/app/gen-server/lib/homedb/UsersManager.ts index 6a0f431c84..7472152409 100644 --- a/app/gen-server/lib/homedb/UsersManager.ts +++ b/app/gen-server/lib/homedb/UsersManager.ts @@ -27,6 +27,8 @@ import { Pref } from 'app/gen-server/entity/Pref'; import flatten from 'lodash/flatten'; import { EntityManager } from 'typeorm'; +import { UserTypesStrings } from 'app/common/User'; + // A special user allowed to add/remove the EVERYONE_EMAIL to/from a resource. export const SUPPORT_EMAIL = appSettings.section('access').flag('supportEmail').requireString({ envVar: 'GRIST_SUPPORT_EMAIL', @@ -371,7 +373,7 @@ export class UsersManager { * unset/outdated fields of an existing record. * */ - public async getUserByLogin(email: string, options: GetUserOptions = {}) { + public async getUserByLogin(email: string, options: GetUserOptions = {}, type?: UserTypesStrings) { const {manager: transaction, profile, userOptions} = options; const normalizedEmail = normalizeEmail(email); return await this._runInTransaction(transaction, async manager => { @@ -389,6 +391,8 @@ export class UsersManager { // Special users do not have first time user set so that they don't get redirected to the // welcome page. user.isFirstTimeUser = !NON_LOGIN_EMAILS.includes(normalizedEmail); + // redémarrer lundi ici TODO + user.type = typeof type === 'undefined' ? 'login' : type; login = new Login(); login.email = normalizedEmail; login.user = user; diff --git a/app/gen-server/migration/1730215435023-ServiceAccounts.ts b/app/gen-server/migration/1730215435023-ServiceAccounts.ts index 5b217365a1..eb667f7281 100644 --- a/app/gen-server/migration/1730215435023-ServiceAccounts.ts +++ b/app/gen-server/migration/1730215435023-ServiceAccounts.ts @@ -23,55 +23,48 @@ export class ServiceAccounts1730215435023 implements MigrationInterface { isPrimary: true, }, { - name: 'description', - type: 'varchar' + name: 'owner_id', + type: 'int', }, { - name: 'endOfLife', - type: datetime, - isNullable: false, + name: 'service_user_id', + type: 'int', }, - ], - }) - ); - await queryRunner.createTable( - new Table({ - name: 'service_account_user', - columns: [ { - name: 'service_account_id', - type: 'int', + name: 'description', + type: 'varchar', }, { - name: 'user_id', - type: 'int' + name: 'endOfLife', + type: datetime, + isNullable: false, }, ], }) ); await queryRunner.createForeignKey( - 'service_account_user', + 'service_accounts', new TableForeignKey({ - columnNames: ['service_account_id'], + columnNames: ['service_user_id'], referencedColumnNames: ['id'], - referencedTableName: 'service_accounts', + referencedTableName: 'users', onDelete: 'CASCADE', }) ); await queryRunner.createForeignKey( - 'service_account_user', + 'service_accounts', new TableForeignKey({ - columnNames: ['user_id'], + columnNames: ['owner_id'], referencedColumnNames: ['id'], referencedTableName: 'users', onDelete: 'CASCADE', }) ); await queryRunner.createIndex( - 'service_account_user', + 'service_accounts', new TableIndex({ - name: 'service_account__user', - columnNames: ['service_account_id', 'user_id'], + name: 'service_account__owner', + columnNames: ['service_accounts_owner', 'user_id'], }) ); } @@ -79,6 +72,5 @@ export class ServiceAccounts1730215435023 implements MigrationInterface { public async down(queryRunner: QueryRunner): Promise { await queryRunner.dropColumn('users', 'type'); await queryRunner.dropTable('service_accounts'); - await queryRunner.dropTable('service_account_user'); } } diff --git a/test/gen-server/ApiServer.ts b/test/gen-server/ApiServer.ts index 3d03a0a7f8..9f291f4610 100644 --- a/test/gen-server/ApiServer.ts +++ b/test/gen-server/ApiServer.ts @@ -2378,9 +2378,7 @@ describe('ApiServer', function() { afterEach(async function() { oldEnv.restore(); - // FIXME create the new method to delete services accounts - //const did = await dbManager.testGetId('Curiosity'); - // await dbManager.deleteServices(did as string); + await dbManager.deleteAllServiceAccounts(); }); after(async function() { @@ -2448,6 +2446,10 @@ describe('ApiServer', function() { // it('Endpoint UPDATE /api/service-accounts/{saId}/transfer-to/{userId}', async function() { // }); + + // it('MUSN'T connect as a login user, async function() { + + //}); }); });