Skip to content

Commit c251a69

Browse files
committed
[server] make first user owner
1 parent 8f85d82 commit c251a69

File tree

3 files changed

+21
-16
lines changed

3 files changed

+21
-16
lines changed

components/server/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
"start": "node ./dist/main.js",
88
"start-inspect": "node --inspect=0.0.0.0:9229 ./dist/main.js",
99
"generate": "leeway run components/spicedb:generate-ts > src/authorization/definitions.ts && npx prettier --write src/authorization/definitions.ts",
10-
"build": "yarn generate && yarn lint && npx tsc",
10+
"build": "yarn clean && yarn generate && yarn lint && npx tsc",
1111
"lint": "yarn eslint src/*.ts src/**/*.ts",
1212
"lint:fix": "yarn eslint src/*.ts src/**/*.ts --fix",
13-
"build:clean": "yarn clean && yarn build",
1413
"rebuild": "yarn build:clean",
1514
"build:watch": "watch 'yarn build' .",
1615
"watch": "leeway exec --package .:app --transitive-dependencies --filter-type yarn --components --parallel -- yarn build -w --preserveWatchOutput",

components/server/src/orgs/organization-service.spec.db.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ describe("OrganizationService", async () => {
120120
owner = previouslyMember;
121121

122122
// owner can downgrade themselves only if they are not the last owner
123-
await expectError(ErrorCodes.CONFLICT, os.addOrUpdateMember(owner.id, org.id, owner.id, "member"));
123+
await os.addOrUpdateMember(owner.id, org.id, owner.id, "member");
124+
// verify they are still an owner
125+
const members = await os.listMembers(owner.id, org.id);
126+
expect(members.some((m) => m.userId === owner.id && m.role === "owner")).to.be.true;
124127

125128
// owner can delete themselves only if they are not the last owner
126129
await expectError(ErrorCodes.CONFLICT, os.removeOrganizationMember(owner.id, org.id, owner.id));

components/server/src/orgs/organization-service.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,16 @@ export class OrganizationService {
187187
if (userId) {
188188
await this.auth.checkPermissionOnOrganization(userId, "write_members", orgId);
189189
}
190-
if (role !== "owner") {
191-
const members = await this.teamDB.findMembersByTeam(orgId);
192-
if (!members.some((m) => m.userId !== memberId && m.role === "owner")) {
193-
throw new ApplicationError(ErrorCodes.CONFLICT, "Cannot remove the last owner of an organization.");
194-
}
195-
}
196190
const members = await this.teamDB.findMembersByTeam(orgId);
197-
const firstMember = members.filter((m) => m.userId !== BUILTIN_INSTLLATION_ADMIN_USER_ID).length === 0;
198-
if (firstMember) {
199-
// first member (that is not an admin) is going to be an owner
191+
const hasOtherRegularOwners =
192+
members.filter(
193+
(m) =>
194+
m.userId !== BUILTIN_INSTLLATION_ADMIN_USER_ID && //
195+
m.userId !== memberId && //
196+
m.role === "owner",
197+
).length > 0;
198+
if (!hasOtherRegularOwners) {
199+
// first regular member is going to be an owner
200200
role = "owner";
201201
log.info({ userId: memberId }, "First member of organization, setting role to owner.");
202202
}
@@ -208,12 +208,15 @@ export class OrganizationService {
208208
await this.auth.addOrganizationRole(orgId, memberId, role);
209209
});
210210
} catch (err) {
211-
//TODO simply removing the user is not necessarily the right thing to do here, as the user might have been a member before
212-
await this.auth.removeOrganizationRole(orgId, memberId, "member");
211+
await this.auth.removeOrganizationRole(
212+
orgId,
213+
memberId,
214+
members.find((m) => m.userId === memberId)?.role || "member",
215+
);
213216
throw err;
214217
}
215-
// we can remove the built-in installation admin now
216-
if (firstMember) {
218+
// we can remove the built-in installation admin if we have added an owner
219+
if (!hasOtherRegularOwners) {
217220
try {
218221
await this.removeOrganizationMember(memberId, orgId, BUILTIN_INSTLLATION_ADMIN_USER_ID);
219222
} catch (error) {

0 commit comments

Comments
 (0)