diff --git a/.vscode/settings.json b/.vscode/settings.json index 28cde63..13d2d7c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,19 @@ { "editor.fontFamily": "'FiraCode Nerd Font Mono',Menlo, Monaco, 'Courier New', monospace", "terminal.integrated.fontFamily": "'FiraCode Nerd Font Mono'", - "markdown.preview.fontFamily": "'FiraCode Nerd Font Mono',-apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif" + "markdown.preview.fontFamily": "'FiraCode Nerd Font Mono',-apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif", + "sqltools.connections": [ + { + "ssh": "Disabled", + "previewLimit": 50, + "server": "localhost", + "port": 4301, + "driver": "PostgreSQL", + "name": "dvbooking-dev", + "group": "dvbooking", + "database": "dvbooking", + "username": "postgres", + "password": "test" + } + ] } \ No newline at end of file diff --git a/server/src/migration/1763106308124-add_non_admin_users.ts b/server/src/migration/1763106308124-add_non_admin_users.ts new file mode 100644 index 0000000..81b8059 --- /dev/null +++ b/server/src/migration/1763106308124-add_non_admin_users.ts @@ -0,0 +1,100 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddNonAdminUsers1763106308124 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + // 1. Create 'user' Role if it doesn't exist + const roles = await queryRunner.query( + `SELECT id FROM "user_role" WHERE "name" = 'user'`, + ); + let userRoleId: number; + if (roles.length === 0) { + const insertRole = await queryRunner.query( + `INSERT INTO "user_role" ("name") VALUES ('user') RETURNING id`, + ); + userRoleId = insertRole[0].id; + } else { + userRoleId = roles[0].id; + } + + // 2. Create 'user' Group if it doesn't exist + const groups = await queryRunner.query( + `SELECT id FROM "user_group" WHERE "name" = 'user'`, + ); + let userGroupId: number; + if (groups.length === 0) { + const insertGroup = await queryRunner.query( + `INSERT INTO "user_group" ("name") VALUES ('user') RETURNING id`, + ); + userGroupId = insertGroup[0].id; + } else { + userGroupId = groups[0].id; + } + + // 3. Link Group to Role if not linked + const groupRoles = await queryRunner.query( + `SELECT * FROM "user_group_roles_user_role" WHERE "userGroupId" = $1 AND "userRoleId" = $2`, + [userGroupId, userRoleId], + ); + if (groupRoles.length === 0) { + await queryRunner.query( + `INSERT INTO "user_group_roles_user_role" ("userGroupId", "userRoleId") VALUES ($1, $2)`, + [userGroupId, userRoleId], + ); + } + + // 4. Create 3 Users + const passwordHash = '$2a$12$sT7bIBfUdAvCzcwyppSX/uVd4EP6ORgWiEg7jqXvMKJErR5jWhnmO'; // '123456' + const usersToCreate = [ + { username: 'user1', email: 'user1@test.com' }, + { username: 'user2', email: 'user2@test.com' }, + { username: 'user3', email: 'user3@test.com' }, + ]; + + for (const userData of usersToCreate) { + const existingUser = await queryRunner.query( + `SELECT id FROM "user" WHERE "username" = $1`, + [userData.username], + ); + + let userId: number; + if (existingUser.length === 0) { + const insertUser = await queryRunner.query( + `INSERT INTO "user" ("username", "email", "password") VALUES ($1, $2, $3) RETURNING id`, + [userData.username, userData.email, passwordHash], + ); + userId = insertUser[0].id; + } else { + userId = existingUser[0].id; + } + + // 5. Link User to Group + const userToGroup = await queryRunner.query( + `SELECT * FROM "user_groups_user_group" WHERE "userId" = $1 AND "userGroupId" = $2`, + [userId, userGroupId], + ); + if (userToGroup.length === 0) { + await queryRunner.query( + `INSERT INTO "user_groups_user_group" ("userId", "userGroupId") VALUES ($1, $2)`, + [userId, userGroupId], + ); + } + } + } + + public async down(queryRunner: QueryRunner): Promise { + const usernames = ['user1', 'user2', 'user3']; + + for (const username of usernames) { + const user = await queryRunner.query(`SELECT id FROM "user" WHERE "username" = $1`, [username]); + if (user.length > 0) { + const userId = user[0].id; + await queryRunner.query(`DELETE FROM "user_groups_user_group" WHERE "userId" = $1`, [userId]); + await queryRunner.query(`DELETE FROM "user" WHERE "id" = $1`, [userId]); + } + } + + // We might not want to delete the 'user' group and role as they might be used by others, + // but for completeness of this migration's "down" if they were created here: + // However, usually it's safer to just leave the schema-level definitions if they are generic. + } +}