mirror of
https://github.com/AtHeartEngineering/bandada.git
synced 2026-01-09 20:28:06 -05:00
refactor: separate manual vs apikey logic in group service
This commit is contained in:
@@ -2,11 +2,13 @@ import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
Index,
|
||||
PrimaryColumn,
|
||||
UpdateDateColumn
|
||||
} from "typeorm"
|
||||
|
||||
@Entity("admins")
|
||||
@Index(["apiKey"], { unique: true })
|
||||
export class Admin {
|
||||
@PrimaryColumn({ unique: true })
|
||||
id: string
|
||||
|
||||
@@ -416,7 +416,6 @@ describe("GroupsService", () => {
|
||||
it("Should create a group via API", async () => {
|
||||
const group = await groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
@@ -432,15 +431,10 @@ describe("GroupsService", () => {
|
||||
it("Should remove a group via API", async () => {
|
||||
const group = await groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
await groupsService.removeGroupWithAPIKey(
|
||||
group.id,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
await groupsService.removeGroupWithAPIKey(group.id, apiKey)
|
||||
|
||||
const fun = groupsService.getGroup(group.id)
|
||||
|
||||
@@ -450,69 +444,51 @@ describe("GroupsService", () => {
|
||||
})
|
||||
|
||||
it("Should not create a group if the admin does not exist", async () => {
|
||||
const fun = groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
"wrong",
|
||||
apiKey
|
||||
)
|
||||
const fun = groupsService.createGroupWithAPIKey(groupDto, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(`Invalid admin for the groups`)
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not remove a group if the admin does not exist", async () => {
|
||||
const group = await groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
const fun = groupsService.removeGroupWithAPIKey(
|
||||
group.id,
|
||||
"wrong",
|
||||
apiKey
|
||||
)
|
||||
const fun = groupsService.removeGroupWithAPIKey(group.id, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(`Invalid admin for the groups`)
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not create a group if the API key is invalid", async () => {
|
||||
const fun = groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
admin.id,
|
||||
"apiKey"
|
||||
)
|
||||
const fun = groupsService.createGroupWithAPIKey(groupDto, "apiKey")
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not remove a group if the API key is invalid", async () => {
|
||||
const group = await groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
const fun = groupsService.removeGroupWithAPIKey(
|
||||
group.id,
|
||||
admin.id,
|
||||
"wrong"
|
||||
)
|
||||
const fun = groupsService.removeGroupWithAPIKey(group.id, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not create a group if the API key is disabled for the admin", async () => {
|
||||
await adminsService.updateApiKey(admin.id, ApiKeyActions.Disable)
|
||||
|
||||
const fun = groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
const fun = groupsService.createGroupWithAPIKey(groupDto, apiKey)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
@@ -524,17 +500,12 @@ describe("GroupsService", () => {
|
||||
|
||||
const group = await groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
await adminsService.updateApiKey(admin.id, ApiKeyActions.Disable)
|
||||
|
||||
const fun = groupsService.removeGroupWithAPIKey(
|
||||
group.id,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
const fun = groupsService.removeGroupWithAPIKey(group.id, apiKey)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
@@ -546,7 +517,6 @@ describe("GroupsService", () => {
|
||||
|
||||
const group = await groupsService.createGroupWithAPIKey(
|
||||
groupDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
@@ -564,7 +534,6 @@ describe("GroupsService", () => {
|
||||
|
||||
const fun = groupsService.removeGroupWithAPIKey(
|
||||
group.id,
|
||||
anotherAdmin.id,
|
||||
anotherApiKey
|
||||
)
|
||||
|
||||
@@ -619,7 +588,6 @@ describe("GroupsService", () => {
|
||||
it("Should create the groups via API", async () => {
|
||||
const groups = await groupsService.createGroupsWithAPIKey(
|
||||
groupsDtos,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
@@ -644,11 +612,7 @@ describe("GroupsService", () => {
|
||||
|
||||
expect(groups).toHaveLength(4)
|
||||
|
||||
await groupsService.removeGroupsWithAPIKey(
|
||||
[ids[0], ids[1]],
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
await groupsService.removeGroupsWithAPIKey([ids[0], ids[1]], apiKey)
|
||||
|
||||
groups = await groupsService.getGroups({
|
||||
adminId: admin.id
|
||||
@@ -677,55 +641,45 @@ describe("GroupsService", () => {
|
||||
it("Should not create the groups if the admin does not exist", async () => {
|
||||
const fun = groupsService.createGroupsWithAPIKey(
|
||||
groupsDtos,
|
||||
"wrong",
|
||||
apiKey
|
||||
"wrong"
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(`Invalid admin for the groups`)
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not remove the groups if the admin does not exist", async () => {
|
||||
const fun = groupsService.removeGroupsWithAPIKey(
|
||||
ids,
|
||||
"wrong",
|
||||
apiKey
|
||||
)
|
||||
const fun = groupsService.removeGroupsWithAPIKey(ids, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(`Invalid admin for the groups`)
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not create the groups if the API key is invalid", async () => {
|
||||
const fun = groupsService.createGroupsWithAPIKey(
|
||||
groupsDtos,
|
||||
admin.id,
|
||||
"apiKey"
|
||||
"wrong"
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not remove the groups if the API key is invalid", async () => {
|
||||
const fun = groupsService.removeGroupsWithAPIKey(
|
||||
ids,
|
||||
admin.id,
|
||||
"apiKey"
|
||||
)
|
||||
const fun = groupsService.removeGroupsWithAPIKey(ids, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not create the groups if the API key is disabled for the admin", async () => {
|
||||
await adminsService.updateApiKey(admin.id, ApiKeyActions.Disable)
|
||||
|
||||
const fun = groupsService.createGroupsWithAPIKey(
|
||||
groupsDtos,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
const fun = groupsService.createGroupsWithAPIKey(groupsDtos, apiKey)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
@@ -733,11 +687,7 @@ describe("GroupsService", () => {
|
||||
})
|
||||
|
||||
it("Should not remove the groups if the API key is disabled for the admin", async () => {
|
||||
const fun = groupsService.removeGroupsWithAPIKey(
|
||||
ids,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
const fun = groupsService.removeGroupsWithAPIKey(ids, apiKey)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
@@ -759,7 +709,6 @@ describe("GroupsService", () => {
|
||||
|
||||
const fun = groupsService.removeGroupsWithAPIKey(
|
||||
[ids[2]],
|
||||
anotherAdmin.id,
|
||||
anotherApiKey
|
||||
)
|
||||
|
||||
@@ -805,7 +754,6 @@ describe("GroupsService", () => {
|
||||
const updatedGroup = await groupsService.updateGroupWithApiKey(
|
||||
group.id,
|
||||
updateDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
@@ -825,25 +773,23 @@ describe("GroupsService", () => {
|
||||
const fun = groupsService.updateGroupWithApiKey(
|
||||
groupId,
|
||||
groupDto,
|
||||
"wrong-admin",
|
||||
apiKey
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid admin for the group '${groupId}'`
|
||||
`You are not the admin of the group '${groupId}'`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not update a group if the group does not exist", async () => {
|
||||
const fun = groupsService.updateGroupWithApiKey(
|
||||
"wrong-group",
|
||||
"wrong",
|
||||
groupDto,
|
||||
admin.id,
|
||||
apiKey
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Group with id 'wrong-group' does not exist`
|
||||
`Group with id 'wrong' does not exist`
|
||||
)
|
||||
})
|
||||
|
||||
@@ -851,12 +797,11 @@ describe("GroupsService", () => {
|
||||
const fun = groupsService.updateGroupWithApiKey(
|
||||
groupId,
|
||||
groupDto,
|
||||
admin.id,
|
||||
"invalid-apikey"
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
@@ -866,7 +811,132 @@ describe("GroupsService", () => {
|
||||
const fun = groupsService.updateGroupWithApiKey(
|
||||
groupId,
|
||||
groupDto,
|
||||
apiKey
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("# Update groups via API", () => {
|
||||
const groupsDtos: Array<CreateGroupDto> = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Group1",
|
||||
description: "This is a new group1",
|
||||
treeDepth: 16,
|
||||
fingerprintDuration: 3600
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Group2",
|
||||
description: "This is a new group2",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 7200
|
||||
}
|
||||
]
|
||||
|
||||
const updateDtos: Array<UpdateGroupDto> = [
|
||||
{
|
||||
description: "This is a new new group1",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 7200
|
||||
},
|
||||
{
|
||||
description: "This is a new new group2",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 14400
|
||||
}
|
||||
]
|
||||
let admin: Admin
|
||||
let apiKey: string
|
||||
let groups: Array<Group>
|
||||
let groupId1: string
|
||||
let groupId2: string
|
||||
|
||||
beforeAll(async () => {
|
||||
admin = await adminsService.create({
|
||||
id: "admin",
|
||||
address: "0x"
|
||||
})
|
||||
|
||||
admin = await adminsService.findOne({ id: admin.id })
|
||||
apiKey = await adminsService.updateApiKey(
|
||||
admin.id,
|
||||
ApiKeyActions.Generate
|
||||
)
|
||||
groups = await groupsService.createGroupsManually(
|
||||
groupsDtos,
|
||||
admin.id
|
||||
)
|
||||
groupId1 = groups[0].id
|
||||
groupId2 = groups[1].id
|
||||
})
|
||||
|
||||
it("Should update the groups via API", async () => {
|
||||
const updatedGroups = await groupsService.updateGroupsWithApiKey(
|
||||
[groupId1, groupId2],
|
||||
updateDtos,
|
||||
apiKey
|
||||
)
|
||||
|
||||
updatedGroups.forEach((updatedGroup: Group, i: number) => {
|
||||
expect(updatedGroup.id).toBe(groupsDtos[i].id)
|
||||
expect(updatedGroup.adminId).toBe(admin.id)
|
||||
expect(updatedGroup.description).toBe(updateDtos[i].description)
|
||||
expect(updatedGroup.name).toBe(groupsDtos[i].name)
|
||||
expect(updatedGroup.treeDepth).toBe(updateDtos[i].treeDepth)
|
||||
expect(updatedGroup.fingerprintDuration).toBe(
|
||||
updateDtos[i].fingerprintDuration
|
||||
)
|
||||
expect(updatedGroup.members).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
it("Should not update the groups if the admin is the wrong one", async () => {
|
||||
const fun = groupsService.updateGroupsWithApiKey(
|
||||
[groupId1, groupId2],
|
||||
groupsDtos,
|
||||
"wrong"
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not update the groups if the group does not exist", async () => {
|
||||
const fun = groupsService.updateGroupsWithApiKey(
|
||||
["wrong"],
|
||||
groupsDtos,
|
||||
apiKey
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Group with id 'wrong' does not exist`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not update the groups if the API key is invalid", async () => {
|
||||
const fun = groupsService.updateGroupsWithApiKey(
|
||||
[groupId1, groupId2],
|
||||
groupsDtos,
|
||||
"invalid-apikey"
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not update the groups if the API key is disabled", async () => {
|
||||
await adminsService.updateApiKey(admin.id, ApiKeyActions.Disable)
|
||||
|
||||
const fun = groupsService.updateGroupsWithApiKey(
|
||||
[groupId1, groupId2],
|
||||
groupsDtos,
|
||||
apiKey
|
||||
)
|
||||
|
||||
@@ -1283,6 +1353,402 @@ describe("GroupsService", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("# createGroupManually", () => {
|
||||
const groupDto: CreateGroupDto = {
|
||||
id: "1",
|
||||
name: "Group1",
|
||||
description: "This is a new group1",
|
||||
treeDepth: 16,
|
||||
fingerprintDuration: 3600
|
||||
}
|
||||
let admin: Admin
|
||||
|
||||
beforeAll(async () => {
|
||||
admin = await adminsService.create({
|
||||
id: "admin",
|
||||
address: "0x"
|
||||
})
|
||||
|
||||
admin = await adminsService.findOne({ id: admin.id })
|
||||
})
|
||||
|
||||
it("Should create a group manually", async () => {
|
||||
const group = await groupsService.createGroupManually(
|
||||
groupDto,
|
||||
admin.id
|
||||
)
|
||||
|
||||
expect(group.id).toBe(groupDto.id)
|
||||
expect(group.adminId).toBe(admin.id)
|
||||
expect(group.description).toBe(groupDto.description)
|
||||
expect(group.name).toBe(groupDto.name)
|
||||
expect(group.treeDepth).toBe(groupDto.treeDepth)
|
||||
expect(group.fingerprintDuration).toBe(groupDto.fingerprintDuration)
|
||||
expect(group.members).toHaveLength(0)
|
||||
})
|
||||
|
||||
it("Should not create a group manually if the admin doesn't exist", async () => {
|
||||
const fun = groupsService.createGroupManually(groupDto, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(`You are not an admin`)
|
||||
})
|
||||
})
|
||||
|
||||
describe("# createGroupsManually", () => {
|
||||
const groupsDtos: Array<CreateGroupDto> = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Group1",
|
||||
description: "This is a new group1",
|
||||
treeDepth: 16,
|
||||
fingerprintDuration: 3600
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Group2",
|
||||
description: "This is a new group2",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 7200
|
||||
}
|
||||
]
|
||||
let admin: Admin
|
||||
|
||||
beforeAll(async () => {
|
||||
admin = await adminsService.create({
|
||||
id: "admin",
|
||||
address: "0x"
|
||||
})
|
||||
|
||||
admin = await adminsService.findOne({ id: admin.id })
|
||||
})
|
||||
|
||||
it("Should create a group manually", async () => {
|
||||
const groups = await groupsService.createGroupsManually(
|
||||
groupsDtos,
|
||||
admin.id
|
||||
)
|
||||
|
||||
groups.forEach((group: Group, i: number) => {
|
||||
expect(group.id).toBe(groupsDtos[i].id)
|
||||
expect(group.adminId).toBe(admin.id)
|
||||
expect(group.description).toBe(groupsDtos[i].description)
|
||||
expect(group.name).toBe(groupsDtos[i].name)
|
||||
expect(group.treeDepth).toBe(groupsDtos[i].treeDepth)
|
||||
expect(group.fingerprintDuration).toBe(
|
||||
groupsDtos[i].fingerprintDuration
|
||||
)
|
||||
expect(group.members).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
it("Should not create a group manually if the admin doesn't exist", async () => {
|
||||
const fun = groupsService.createGroupsManually(groupsDtos, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(`You are not an admin`)
|
||||
})
|
||||
})
|
||||
|
||||
describe("# removeGroupManually", () => {
|
||||
const groupDto: CreateGroupDto = {
|
||||
id: "1",
|
||||
name: "Group1",
|
||||
description: "This is a new group1",
|
||||
treeDepth: 16,
|
||||
fingerprintDuration: 3600
|
||||
}
|
||||
let admin: Admin
|
||||
let group: Group
|
||||
|
||||
beforeAll(async () => {
|
||||
admin = await adminsService.create({
|
||||
id: "admin",
|
||||
address: "0x"
|
||||
})
|
||||
|
||||
admin = await adminsService.findOne({ id: admin.id })
|
||||
|
||||
group = await groupsService.createGroupManually(groupDto, admin.id)
|
||||
})
|
||||
|
||||
it("Should remove a group manually", async () => {
|
||||
await groupsService.removeGroupManually(group.id, admin.id)
|
||||
|
||||
const fun = groupsService.getGroup(group.id)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Group with id '${group.id}' does not exist`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not remove a group manually if the group doesn't exist", async () => {
|
||||
const fun = groupsService.removeGroupManually(group.id, admin.id)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Group with id '${group.id}' does not exist`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not remove a group manually if the admin doesn't exist or is not the admin of the group", async () => {
|
||||
group = await groupsService.createGroupManually(groupDto, admin.id)
|
||||
|
||||
const fun = groupsService.removeGroupManually(group.id, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`You are not the admin of the group '${group.id}'`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("# removeGroupsManually", () => {
|
||||
const groupsDtos: Array<CreateGroupDto> = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Group1",
|
||||
description: "This is a new group1",
|
||||
treeDepth: 16,
|
||||
fingerprintDuration: 3600
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Group2",
|
||||
description: "This is a new group2",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 7200
|
||||
}
|
||||
]
|
||||
let admin: Admin
|
||||
let groups: Array<Group>
|
||||
let groupId1: string
|
||||
let groupId2: string
|
||||
|
||||
beforeAll(async () => {
|
||||
admin = await adminsService.create({
|
||||
id: "admin",
|
||||
address: "0x"
|
||||
})
|
||||
|
||||
admin = await adminsService.findOne({ id: admin.id })
|
||||
|
||||
groups = await groupsService.createGroupsManually(
|
||||
groupsDtos,
|
||||
admin.id
|
||||
)
|
||||
|
||||
groupId1 = groups[0].id
|
||||
groupId2 = groups[1].id
|
||||
})
|
||||
|
||||
it("Should remove the groups manually", async () => {
|
||||
await groupsService.removeGroupsManually(
|
||||
[groupId1, groupId2],
|
||||
admin.id
|
||||
)
|
||||
|
||||
const fun1 = groupsService.getGroup(groupId1)
|
||||
const fun2 = groupsService.getGroup(groupId2)
|
||||
|
||||
await expect(fun1).rejects.toThrow(
|
||||
`Group with id '${groupId1}' does not exist`
|
||||
)
|
||||
await expect(fun2).rejects.toThrow(
|
||||
`Group with id '${groupId2}' does not exist`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not remove the groups manually if one or more group doesn't exist", async () => {
|
||||
const fun = groupsService.removeGroupsManually(
|
||||
[groupId1, groupId2],
|
||||
admin.id
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Group with id '${groupId1}' does not exist`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not remove the groups manually if the admin doesn't exist or is not the admin of the group", async () => {
|
||||
groups = await groupsService.createGroupsManually(
|
||||
groupsDtos,
|
||||
admin.id
|
||||
)
|
||||
|
||||
const fun = groupsService.removeGroupsManually(
|
||||
[groupId1, groupId2],
|
||||
"wrong"
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`You are not the admin of the group '${groupId1}'`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("# updateGroupManually", () => {
|
||||
const groupDto: CreateGroupDto = {
|
||||
id: "1",
|
||||
name: "Group1",
|
||||
description: "This is a new group1",
|
||||
treeDepth: 16,
|
||||
fingerprintDuration: 3600
|
||||
}
|
||||
|
||||
const updateDto: UpdateGroupDto = {
|
||||
description: "This is a new new group1",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 7200
|
||||
}
|
||||
let admin: Admin
|
||||
let group: Group
|
||||
|
||||
beforeAll(async () => {
|
||||
admin = await adminsService.create({
|
||||
id: "admin",
|
||||
address: "0x"
|
||||
})
|
||||
|
||||
admin = await adminsService.findOne({ id: admin.id })
|
||||
group = await groupsService.createGroupManually(groupDto, admin.id)
|
||||
})
|
||||
|
||||
it("Should update a group manually", async () => {
|
||||
const updatedGroup = await groupsService.updateGroupManually(
|
||||
group.id,
|
||||
updateDto,
|
||||
admin.id
|
||||
)
|
||||
|
||||
expect(updatedGroup.id).toBe(groupDto.id)
|
||||
expect(updatedGroup.adminId).toBe(admin.id)
|
||||
expect(updatedGroup.description).toBe(updateDto.description)
|
||||
expect(updatedGroup.name).toBe(groupDto.name)
|
||||
expect(updatedGroup.treeDepth).toBe(updateDto.treeDepth)
|
||||
expect(updatedGroup.fingerprintDuration).toBe(
|
||||
updateDto.fingerprintDuration
|
||||
)
|
||||
expect(updatedGroup.members).toHaveLength(0)
|
||||
expect(updatedGroup.credentials).toBeNull()
|
||||
})
|
||||
|
||||
it("Should not update a group manually if the group doesn't exist", async () => {
|
||||
const fun = groupsService.updateGroupManually(
|
||||
"wrong",
|
||||
updateDto,
|
||||
admin.id
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Group with id 'wrong' does not exist`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not update a group manually if the admin doesn't exist or is not the admin of the group", async () => {
|
||||
const fun = groupsService.updateGroupManually(
|
||||
group.id,
|
||||
updateDto,
|
||||
"wrong"
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`You are not the admin of the group '${group.id}'`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("# updateGroupsManually", () => {
|
||||
const groupsDtos: Array<CreateGroupDto> = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Group1",
|
||||
description: "This is a new group1",
|
||||
treeDepth: 16,
|
||||
fingerprintDuration: 3600
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Group2",
|
||||
description: "This is a new group2",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 7200
|
||||
}
|
||||
]
|
||||
|
||||
const updateDtos: Array<UpdateGroupDto> = [
|
||||
{
|
||||
description: "This is a new new group1",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 7200
|
||||
},
|
||||
{
|
||||
description: "This is a new new group2",
|
||||
treeDepth: 32,
|
||||
fingerprintDuration: 14400
|
||||
}
|
||||
]
|
||||
let admin: Admin
|
||||
let groups: Array<Group>
|
||||
let groupId1: string
|
||||
let groupId2: string
|
||||
|
||||
beforeAll(async () => {
|
||||
admin = await adminsService.create({
|
||||
id: "admin",
|
||||
address: "0x"
|
||||
})
|
||||
|
||||
admin = await adminsService.findOne({ id: admin.id })
|
||||
groups = await groupsService.createGroupsManually(
|
||||
groupsDtos,
|
||||
admin.id
|
||||
)
|
||||
groupId1 = groups[0].id
|
||||
groupId2 = groups[1].id
|
||||
})
|
||||
|
||||
it("Should update the groups manually", async () => {
|
||||
const updatedGroups = await groupsService.updateGroupsManually(
|
||||
[groupId1, groupId2],
|
||||
updateDtos,
|
||||
admin.id
|
||||
)
|
||||
|
||||
updatedGroups.forEach((updatedGroup: Group, i: number) => {
|
||||
expect(updatedGroup.id).toBe(groupsDtos[i].id)
|
||||
expect(updatedGroup.adminId).toBe(admin.id)
|
||||
expect(updatedGroup.description).toBe(updateDtos[i].description)
|
||||
expect(updatedGroup.name).toBe(groupsDtos[i].name)
|
||||
expect(updatedGroup.treeDepth).toBe(updateDtos[i].treeDepth)
|
||||
expect(updatedGroup.fingerprintDuration).toBe(
|
||||
updateDtos[i].fingerprintDuration
|
||||
)
|
||||
expect(updatedGroup.members).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
it("Should not update the groups manually if one or more groups doesn't exist", async () => {
|
||||
const fun = groupsService.updateGroupsManually(
|
||||
["wrong"],
|
||||
updateDtos,
|
||||
admin.id
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Group with id 'wrong' does not exist`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not update the groups manually if the admin doesn't exist or is not the admin of the groups", async () => {
|
||||
const fun = groupsService.updateGroupsManually(
|
||||
[groupId1, groupId2],
|
||||
updateDtos,
|
||||
"wrong"
|
||||
)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`You are not the admin of the group '${groupId1}'`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("# initialize", () => {
|
||||
it("Should initialize the cached groups", async () => {
|
||||
const currentCachedGroups = await groupsService.getGroups()
|
||||
|
||||
@@ -19,7 +19,7 @@ import { UpdateGroupDto } from "./dto/update-group.dto"
|
||||
import { Group } from "./entities/group.entity"
|
||||
import { Member } from "./entities/member.entity"
|
||||
import { MerkleProof } from "./types"
|
||||
import { adminApiKeyCheck } from "./groups.utils"
|
||||
import { getAndCheckAdmin } from "./groups.utils"
|
||||
|
||||
@Injectable()
|
||||
export class GroupsService {
|
||||
@@ -61,16 +61,14 @@ export class GroupsService {
|
||||
/**
|
||||
* Create a group using API Key.
|
||||
* @param dto External parameters used to create a new group.
|
||||
* @param adminId Admin id.
|
||||
* @param apiKey The API Key.
|
||||
* @returns Created group.
|
||||
*/
|
||||
async createGroupWithAPIKey(
|
||||
dto: CreateGroupDto,
|
||||
adminId: string,
|
||||
apiKey: string
|
||||
): Promise<Group> {
|
||||
const groups = await this.createGroupsWithAPIKey([dto], adminId, apiKey)
|
||||
const groups = await this.createGroupsWithAPIKey([dto], apiKey)
|
||||
|
||||
return groups.at(0)
|
||||
}
|
||||
@@ -78,20 +76,58 @@ export class GroupsService {
|
||||
/**
|
||||
* Create groups using API Key.
|
||||
* @param dtos External parameters used to create new groups.
|
||||
* @param adminId Admin id.
|
||||
* @param apiKey The API Key.
|
||||
* @returns Created groups.
|
||||
*/
|
||||
async createGroupsWithAPIKey(
|
||||
dtos: Array<CreateGroupDto>,
|
||||
adminId: string,
|
||||
apiKey: string
|
||||
): Promise<Array<Group>> {
|
||||
const newGroups: Array<Group> = []
|
||||
|
||||
const admin = await getAndCheckAdmin(this.adminsService, apiKey)
|
||||
|
||||
for await (const dto of dtos) {
|
||||
const group = await this.createGroup(dto, admin.id)
|
||||
|
||||
newGroups.push(group)
|
||||
}
|
||||
|
||||
return newGroups
|
||||
}
|
||||
|
||||
/**
|
||||
* Create group manually without using API Key.
|
||||
* @param dto External parameters used to create a new group.
|
||||
* @param adminId Admin id.
|
||||
* @returns Created group.
|
||||
*/
|
||||
async createGroupManually(
|
||||
dto: CreateGroupDto,
|
||||
adminId: string
|
||||
): Promise<Group> {
|
||||
const admin = await this.adminsService.findOne({ id: adminId })
|
||||
|
||||
await adminApiKeyCheck(admin, apiKey)
|
||||
if (!admin) throw new BadRequestException(`You are not an admin`)
|
||||
|
||||
return this.createGroup(dto, adminId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create groups manually without using API Key.
|
||||
* @param dtos External parameters used to create new groups.
|
||||
* @param adminId Admin id.
|
||||
* @returns Created groups.
|
||||
*/
|
||||
async createGroupsManually(
|
||||
dtos: Array<CreateGroupDto>,
|
||||
adminId: string
|
||||
): Promise<Array<Group>> {
|
||||
const admin = await this.adminsService.findOne({ id: adminId })
|
||||
|
||||
if (!admin) throw new BadRequestException(`You are not an admin`)
|
||||
|
||||
const newGroups: Array<Group> = []
|
||||
|
||||
for await (const dto of dtos) {
|
||||
const group = await this.createGroup(dto, adminId)
|
||||
@@ -160,27 +196,45 @@ export class GroupsService {
|
||||
*/
|
||||
async removeGroupWithAPIKey(
|
||||
groupId: string,
|
||||
adminId: string,
|
||||
apiKey: string
|
||||
): Promise<void> {
|
||||
return this.removeGroupsWithAPIKey([groupId], adminId, apiKey)
|
||||
return this.removeGroupsWithAPIKey([groupId], apiKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove groups using API Key.
|
||||
* @param groupsIds Groups identifiers.
|
||||
* @param adminId Admin id.
|
||||
* @param apiKey the api key.
|
||||
*/
|
||||
async removeGroupsWithAPIKey(
|
||||
groupsIds: Array<string>,
|
||||
adminId: string,
|
||||
apiKey: string
|
||||
): Promise<void> {
|
||||
const admin = await this.adminsService.findOne({ id: adminId })
|
||||
const admin = await getAndCheckAdmin(this.adminsService, apiKey)
|
||||
|
||||
await adminApiKeyCheck(admin, apiKey)
|
||||
for await (const groupId of groupsIds) {
|
||||
await this.removeGroup(groupId, admin.id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a group manually without using API Key.
|
||||
* @param groupId Group id.
|
||||
* @param adminId Admin id.
|
||||
*/
|
||||
async removeGroupManually(groupId: string, adminId: string): Promise<void> {
|
||||
return this.removeGroup(groupId, adminId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove groups manually without using API Key.
|
||||
* @param groupsIds Groups identifiers.
|
||||
* @param adminId Admin id.
|
||||
*/
|
||||
async removeGroupsManually(
|
||||
groupsIds: Array<string>,
|
||||
adminId: string
|
||||
): Promise<void> {
|
||||
for await (const groupId of groupsIds) {
|
||||
await this.removeGroup(groupId, adminId)
|
||||
}
|
||||
@@ -194,6 +248,11 @@ export class GroupsService {
|
||||
async removeGroup(groupId: string, adminId: string): Promise<void> {
|
||||
const group = await this.getGroup(groupId)
|
||||
|
||||
if (!group)
|
||||
throw new BadRequestException(
|
||||
`The group '${groupId}' does not exists`
|
||||
)
|
||||
|
||||
if (group.adminId !== adminId) {
|
||||
throw new UnauthorizedException(
|
||||
`You are not the admin of the group '${groupId}'`
|
||||
@@ -211,23 +270,82 @@ export class GroupsService {
|
||||
* Update a group using API Key.
|
||||
* @param groupId Group id.
|
||||
* @param dto External parameters used to update a group.
|
||||
* @param adminId Group admin id.
|
||||
* @param apiKey the API Key.
|
||||
* @returns Updated group.
|
||||
*/
|
||||
async updateGroupWithApiKey(
|
||||
groupId: string,
|
||||
dto: UpdateGroupDto,
|
||||
adminId: string,
|
||||
apiKey: string
|
||||
): Promise<Group> {
|
||||
const admin = await this.adminsService.findOne({ id: adminId })
|
||||
const admin = await getAndCheckAdmin(this.adminsService, apiKey)
|
||||
|
||||
await adminApiKeyCheck(admin, apiKey, groupId)
|
||||
return this.updateGroup(groupId, dto, admin.id)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update groups using API Key.
|
||||
* @param groupsIds Groups ids.
|
||||
* @param dtos External parameters used to update groups.
|
||||
* @param apiKey the API Key.
|
||||
* @returns Updated group.
|
||||
*/
|
||||
async updateGroupsWithApiKey(
|
||||
groupsIds: Array<string>,
|
||||
dtos: Array<UpdateGroupDto>,
|
||||
apiKey: string
|
||||
): Promise<Array<Group>> {
|
||||
const updatedGroups: Array<Group> = []
|
||||
|
||||
const admin = await getAndCheckAdmin(this.adminsService, apiKey)
|
||||
|
||||
for await (const [index, groupId] of groupsIds.entries()) {
|
||||
const dto = dtos[index]
|
||||
const group = await this.updateGroup(groupId, dto, admin.id)
|
||||
updatedGroups.push(group)
|
||||
}
|
||||
|
||||
return updatedGroups
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a group manually without using API Key.
|
||||
* @param groupId Group id.
|
||||
* @param dto External parameters used to update a group.
|
||||
* @param adminId Group admin id.
|
||||
* @returns Updated group.
|
||||
*/
|
||||
async updateGroupManually(
|
||||
groupId: string,
|
||||
dto: UpdateGroupDto,
|
||||
adminId: string
|
||||
): Promise<Group> {
|
||||
return this.updateGroup(groupId, dto, adminId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update groups manually without using API Key.
|
||||
* @param groupsIds Groups ids.
|
||||
* @param dtos External parameters used to update groups.
|
||||
* @param adminId Group admin id.
|
||||
* @returns Updated groups.
|
||||
*/
|
||||
async updateGroupsManually(
|
||||
groupsIds: Array<string>,
|
||||
dtos: Array<UpdateGroupDto>,
|
||||
adminId: string
|
||||
): Promise<Array<Group>> {
|
||||
const updatedGroups: Array<Group> = []
|
||||
|
||||
for await (const [index, groupId] of groupsIds.entries()) {
|
||||
const dto = dtos[index]
|
||||
const group = await this.updateGroup(groupId, dto, adminId)
|
||||
updatedGroups.push(group)
|
||||
}
|
||||
|
||||
return updatedGroups
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates some parameters of the group.
|
||||
* @param groupId Group id.
|
||||
@@ -247,6 +365,11 @@ export class GroupsService {
|
||||
): Promise<Group> {
|
||||
const group = await this.getGroup(groupId)
|
||||
|
||||
if (!group)
|
||||
throw new BadRequestException(
|
||||
`The group '${groupId}' does not exists`
|
||||
)
|
||||
|
||||
if (group.adminId !== adminId) {
|
||||
throw new UnauthorizedException(
|
||||
`You are not the admin of the group '${groupId}'`
|
||||
|
||||
@@ -1,6 +1,47 @@
|
||||
import { mapGroupToResponseDTO } from "./groups.utils"
|
||||
import { ScheduleModule } from "@nestjs/schedule"
|
||||
import { Test } from "@nestjs/testing"
|
||||
import { TypeOrmModule } from "@nestjs/typeorm"
|
||||
import { ApiKeyActions } from "@bandada/utils"
|
||||
import { Invite } from "../invites/entities/invite.entity"
|
||||
import { InvitesService } from "../invites/invites.service"
|
||||
import { OAuthAccount } from "../credentials/entities/credentials-account.entity"
|
||||
import { Group } from "./entities/group.entity"
|
||||
import { Member } from "./entities/member.entity"
|
||||
import { GroupsService } from "./groups.service"
|
||||
import { AdminsService } from "../admins/admins.service"
|
||||
import { AdminsModule } from "../admins/admins.module"
|
||||
import { Admin } from "../admins/entities/admin.entity"
|
||||
import { mapGroupToResponseDTO, getAndCheckAdmin } from "./groups.utils"
|
||||
|
||||
describe("Groups utils", () => {
|
||||
let groupsService: GroupsService
|
||||
let adminsService: AdminsService
|
||||
|
||||
beforeAll(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [
|
||||
TypeOrmModule.forRootAsync({
|
||||
useFactory: () => ({
|
||||
type: "sqlite",
|
||||
database: ":memory:",
|
||||
dropSchema: true,
|
||||
entities: [Group, Invite, Member, OAuthAccount, Admin],
|
||||
synchronize: true
|
||||
})
|
||||
}),
|
||||
TypeOrmModule.forFeature([Group, Invite, Member, Admin]),
|
||||
ScheduleModule.forRoot(),
|
||||
AdminsModule
|
||||
],
|
||||
providers: [GroupsService, InvitesService, AdminsService]
|
||||
}).compile()
|
||||
|
||||
groupsService = await module.resolve(GroupsService)
|
||||
adminsService = await module.resolve(AdminsService)
|
||||
|
||||
await groupsService.initialize()
|
||||
})
|
||||
|
||||
describe("# mapGroupToResponseDTO", () => {
|
||||
it("Should map the group data", async () => {
|
||||
const group = {
|
||||
@@ -29,4 +70,68 @@ describe("Groups utils", () => {
|
||||
expect(fingerprint).toBe("12345")
|
||||
})
|
||||
})
|
||||
|
||||
describe("# getAndCheckAdmin", () => {
|
||||
const groupId = "1"
|
||||
let apiKey = ""
|
||||
let admin: Admin = {} as any
|
||||
|
||||
beforeAll(async () => {
|
||||
admin = await adminsService.create({
|
||||
id: groupId,
|
||||
address: "0x00"
|
||||
})
|
||||
|
||||
apiKey = await adminsService.updateApiKey(
|
||||
admin.id,
|
||||
ApiKeyActions.Generate
|
||||
)
|
||||
|
||||
admin = await adminsService.findOne({ id: admin.id })
|
||||
})
|
||||
|
||||
it("Should successfully check and return the admin", async () => {
|
||||
const checkedAdmin = await getAndCheckAdmin(adminsService, apiKey)
|
||||
|
||||
expect(checkedAdmin.id).toBe(admin.id)
|
||||
expect(checkedAdmin.address).toBe(admin.address)
|
||||
expect(checkedAdmin.apiKey).toBe(admin.apiKey)
|
||||
expect(checkedAdmin.apiEnabled).toBe(admin.apiEnabled)
|
||||
expect(checkedAdmin.username).toBe(admin.username)
|
||||
})
|
||||
|
||||
it("Should throw if the API Key or admin is invalid", async () => {
|
||||
const fun = getAndCheckAdmin(adminsService, "wrong")
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should throw if the API Key or admin is invalid (w/ group identifier)", async () => {
|
||||
const fun = getAndCheckAdmin(adminsService, "wrong", groupId)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or invalid admin for the group '${groupId}'`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should throw if the API Key is invalid or API access is disabled", async () => {
|
||||
await adminsService.updateApiKey(admin.id, ApiKeyActions.Disable)
|
||||
|
||||
const fun = getAndCheckAdmin(adminsService, apiKey)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
)
|
||||
})
|
||||
|
||||
it("Should throw if the API Key is invalid or API access is disabled (w/ group identifier)", async () => {
|
||||
const fun = getAndCheckAdmin(adminsService, apiKey, groupId)
|
||||
|
||||
await expect(fun).rejects.toThrow(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BadRequestException } from "@nestjs/common"
|
||||
import { Group } from "./entities/group.entity"
|
||||
import { Admin } from "../admins/entities/admin.entity"
|
||||
import { AdminsService } from "../admins/admins.service"
|
||||
|
||||
export function mapGroupToResponseDTO(group: Group, fingerprint: string = "") {
|
||||
const dto = {
|
||||
@@ -19,16 +20,18 @@ export function mapGroupToResponseDTO(group: Group, fingerprint: string = "") {
|
||||
return dto
|
||||
}
|
||||
|
||||
export async function adminApiKeyCheck(
|
||||
admin: Admin,
|
||||
export async function getAndCheckAdmin(
|
||||
adminService: AdminsService,
|
||||
apiKey: string,
|
||||
groupId?: string
|
||||
) {
|
||||
if (!admin) {
|
||||
): Promise<Admin> {
|
||||
const admin = await adminService.findOne({ apiKey })
|
||||
|
||||
if (!apiKey || !admin) {
|
||||
throw new BadRequestException(
|
||||
groupId
|
||||
? `Invalid admin for the group '${groupId}'`
|
||||
: `Invalid admin for the groups`
|
||||
? `Invalid API key or invalid admin for the group '${groupId}'`
|
||||
: `Invalid API key or invalid admin for the groups`
|
||||
)
|
||||
}
|
||||
|
||||
@@ -37,4 +40,6 @@ export async function adminApiKeyCheck(
|
||||
`Invalid API key or API access not enabled for admin '${admin.id}'`
|
||||
)
|
||||
}
|
||||
|
||||
return admin
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user