diff --git a/src/lib/services/access-service.ts b/src/lib/services/access-service.ts index 4cd15f3b11..388fc35cfb 100644 --- a/src/lib/services/access-service.ts +++ b/src/lib/services/access-service.ts @@ -457,8 +457,9 @@ export class AccessService { async getRootRoleForUser(userId: number): Promise { const rootRole = await this.store.getRootRoleForUser(userId); if (!rootRole) { - const defaultRole = await this.getPredefinedRole(RoleName.VIEWER); - return defaultRole; + // this should never happen, but before breaking we want to know if it does. + this.logger.warn(`Could not find root role for user=${userId}.`); + return this.getPredefinedRole(RoleName.VIEWER); } return rootRole; } diff --git a/src/migrations/20250320121200-all-users-have-a-root-role.js b/src/migrations/20250320121200-all-users-have-a-root-role.js new file mode 100644 index 0000000000..8f1ab0ad27 --- /dev/null +++ b/src/migrations/20250320121200-all-users-have-a-root-role.js @@ -0,0 +1,20 @@ +exports.up = function (db, cb) { + // add root role Viewer (id 3) to all users who don't have a root role + db.runSql( + `INSERT INTO role_user(role_id, user_id, project) SELECT 3, u.id, 'default' +FROM users u +WHERE u.id > 0 AND u.deleted_at IS NULL AND NOT EXISTS ( + SELECT 1 + FROM role_user ru + JOIN roles r ON ru.role_id = r.id + WHERE ru.user_id = u.id + AND r.type IN ('root', 'root-custom') +);`, + cb, + ); +}; + +exports.down = function (db, callback) { + // No rollback + callback(); +}; \ No newline at end of file