Skip to content

Commit c5721f1

Browse files
authoredFeb 28, 2024··
Merge pull request #785 from eea-oasis/feature/759-create-public-key-schema
Add public key schema to prisma
2 parents 6a3239f + 6f84d1e commit c5721f1

File tree

5 files changed

+157
-11
lines changed

5 files changed

+157
-11
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `publicKey` on the `BpiSubject` table. All the data in the column will be lost.
5+
6+
*/
7+
-- CreateEnum
8+
CREATE TYPE "PublicKeyType" AS ENUM ('ECDSA', 'EDDSA');
9+
10+
-- AlterTable
11+
ALTER TABLE "BpiSubject" DROP COLUMN "publicKey";
12+
13+
-- CreateTable
14+
CREATE TABLE "PublicKey" (
15+
"id" TEXT NOT NULL,
16+
"type" "PublicKeyType" NOT NULL,
17+
"value" TEXT NOT NULL,
18+
"bpiSubjectId" TEXT NOT NULL,
19+
20+
CONSTRAINT "PublicKey_pkey" PRIMARY KEY ("id")
21+
);
22+
23+
-- CreateIndex
24+
CREATE UNIQUE INDEX "PublicKey_value_key" ON "PublicKey"("value");
25+
26+
-- CreateIndex
27+
CREATE UNIQUE INDEX "PublicKey_type_bpiSubjectId_key" ON "PublicKey"("type", "bpiSubjectId");
28+
29+
-- AddForeignKey
30+
ALTER TABLE "PublicKey" ADD CONSTRAINT "PublicKey_bpiSubjectId_fkey" FOREIGN KEY ("bpiSubjectId") REFERENCES "BpiSubject"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

‎examples/bri-3/prisma/schema.prisma

+15-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ model BpiSubject {
1414
id String @id @default(uuid())
1515
name String
1616
description String
17-
publicKey String
17+
publicKeys PublicKey[]
1818
loginNonce String @default("")
1919
ownedBpiSubjectAccounts BpiSubjectAccount[] @relation(name: "ownerBpiSubject_fk")
2020
createdBpiSubjectAccounts BpiSubjectAccount[] @relation(name: "creatorBpiSubject_fk")
@@ -151,7 +151,21 @@ model BpiAccountStateTreeLeafValue {
151151
witness String
152152
}
153153

154+
model PublicKey {
155+
id String @id @default(uuid())
156+
type PublicKeyType
157+
value String @unique
158+
bpiSubjectId String
159+
bpiSubject BpiSubject @relation(fields: [bpiSubjectId], references: [id])
160+
@@unique([type, bpiSubjectId])
161+
}
162+
154163
enum WorkgroupStatus {
155164
ACTIVE
156165
ARCHIVED
157166
}
167+
168+
enum PublicKeyType {
169+
ECDSA
170+
EDDSA
171+
}

‎examples/bri-3/src/bri/identity/bpiSubjects/agents/bpiSubjectsStorage.agent.ts

+53-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { PrismaService } from '../../../../shared/prisma/prisma.service';
44
import { NOT_FOUND_ERR_MESSAGE } from '../api/err.messages';
55
import { BpiSubject } from '../models/bpiSubject';
66
import { BpiSubjectRole, BpiSubjectRoleName } from '../models/bpiSubjectRole';
7+
import { PublicKey, PublicKeyType } from '../models/publicKey';
78

89
// Repositories are the only places that talk the Prisma language of models.
910
// They are always mapped to and from domain objects so that the business layer of the application
@@ -64,8 +65,37 @@ export class BpiSubjectStorageAgent extends PrismaService {
6465
return this.mapper.map(bpiSubjectRole, BpiSubjectRole);
6566
}
6667

68+
async storePublicKey(
69+
id: string,
70+
type: PublicKeyType,
71+
value: string,
72+
bpiSubjectId: string,
73+
): Promise<void> {
74+
await this.prisma.publicKey.create({
75+
data: {
76+
id: id,
77+
type: type,
78+
value: value,
79+
bpiSubjectId: bpiSubjectId,
80+
},
81+
});
82+
}
83+
84+
async updatePublicKey(
85+
type: PublicKeyType,
86+
value: string,
87+
bpiSubjectId: string,
88+
): Promise<PublicKey> {
89+
const updatedPublicKey = await this.prisma.publicKey.update({
90+
where: { type_bpiSubjectId: { type: type, bpiSubjectId: bpiSubjectId } },
91+
data: {
92+
value: value,
93+
},
94+
});
95+
96+
return this.mapper.map(updatedPublicKey, PublicKey);
97+
}
6798
async storeNewBpiSubject(bpiSubject: BpiSubject): Promise<BpiSubject> {
68-
bpiSubject.publicKey = bpiSubject.publicKey.toLowerCase();
6999
const newBpiSubjectModel = await this.prisma.bpiSubject.create({
70100
data: {
71101
...bpiSubject,
@@ -76,6 +106,13 @@ export class BpiSubjectStorageAgent extends PrismaService {
76106
};
77107
}),
78108
},
109+
publicKey: {
110+
connect: bpiSubject.publicKeys.map((pk) => {
111+
return {
112+
id: pk.id,
113+
};
114+
}),
115+
},
79116
},
80117
});
81118

@@ -94,6 +131,13 @@ export class BpiSubjectStorageAgent extends PrismaService {
94131
};
95132
}),
96133
},
134+
publicKey: {
135+
connect: bpiSubject.publicKeys.map((pk) => {
136+
return {
137+
id: pk.id,
138+
};
139+
}),
140+
},
97141
},
98142
});
99143
return this.mapper.map(updatedBpiSubjectModel, BpiSubject);
@@ -105,15 +149,20 @@ export class BpiSubjectStorageAgent extends PrismaService {
105149
});
106150
}
107151

108-
async getBpiSubjectByPublicKey(publicKey: string): Promise<BpiSubject> {
152+
async getBpiSubjectByPublicKey(publicKeyValue: string): Promise<BpiSubject> {
109153
const bpiSubjectModel = await this.prisma.bpiSubject.findFirst({
110154
where: {
111-
publicKey: publicKey,
155+
publicKey: {
156+
some: {
157+
value: publicKeyValue,
158+
},
159+
},
112160
},
113161
include: {
114-
roles: true,
162+
publicKey: true,
115163
},
116164
});
165+
117166
if (!bpiSubjectModel) {
118167
throw new NotFoundException(NOT_FOUND_ERR_MESSAGE);
119168
}

‎examples/bri-3/src/bri/identity/bpiSubjects/models/bpiSubject.ts

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { AutoMap } from '@automapper/classes';
22
import { v4 } from 'uuid';
33
import { BpiSubjectRole } from './bpiSubjectRole';
4+
import { PublicKeyType, PublicKey } from './publicKey';
45

56
export class BpiSubject {
67
@AutoMap()
@@ -13,7 +14,7 @@ export class BpiSubject {
1314
description: string;
1415

1516
@AutoMap()
16-
publicKey: string;
17+
publicKeys: PublicKey[];
1718

1819
@AutoMap()
1920
loginNonce: string;
@@ -24,13 +25,13 @@ export class BpiSubject {
2425
id: string,
2526
name: string,
2627
description: string,
27-
publicKey: string,
28+
publicKeys: PublicKey[],
2829
roles: BpiSubjectRole[],
2930
) {
3031
this.id = id;
3132
this.name = name;
3233
this.description = description;
33-
this.publicKey = publicKey;
34+
this.publicKeys = publicKeys;
3435
this.roles = roles;
3536
}
3637

@@ -42,15 +43,20 @@ export class BpiSubject {
4243
this.description = newDescription;
4344
}
4445

45-
public updatePublicKey(newPk: string): void {
46-
this.publicKey = newPk;
46+
public updatePublicKey(newPk: PublicKey): void {
47+
this.publicKeys = this.publicKeys.map((key) =>
48+
key.type == newPk.type ? (key = newPk) : key,
49+
);
4750
}
4851

4952
public updateLoginNonce(): void {
5053
this.loginNonce = v4();
5154
}
5255

5356
public getBpiSubjectDid(): string {
54-
return `did:ethr:0x5:${this.publicKey}`;
57+
const ecdsaPublicKey = this.publicKeys.filter(
58+
(key) => key.type == PublicKeyType.ECDSA,
59+
)[0];
60+
return `did:ethr:0x5:${ecdsaPublicKey.value}`;
5561
}
5662
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { AutoMap } from '@automapper/classes';
2+
import { BpiSubject } from './bpiSubject';
3+
4+
export enum PublicKeyType {
5+
ECDSA = 'ECDSA',
6+
EDDSA = 'EDDSA',
7+
}
8+
export class PublicKey {
9+
@AutoMap()
10+
id: string;
11+
12+
@AutoMap()
13+
type: PublicKeyType;
14+
15+
@AutoMap()
16+
value: string;
17+
18+
@AutoMap()
19+
bpiSubjectId: string;
20+
21+
@AutoMap()
22+
bpiSubject: BpiSubject;
23+
24+
constructor(
25+
id: string,
26+
type: PublicKeyType,
27+
value: string,
28+
bpiSubjectId: string,
29+
) {
30+
this.id = id;
31+
this.type = type;
32+
this.value = value;
33+
this.bpiSubjectId = bpiSubjectId;
34+
}
35+
36+
public updateType(newType: PublicKeyType): void {
37+
this.type = newType;
38+
}
39+
40+
public updateValue(newValue: string): void {
41+
this.value = newValue;
42+
}
43+
44+
public updateBpiSubjectId(newBpiSubjectId: string): void {
45+
this.bpiSubjectId = newBpiSubjectId;
46+
}
47+
}

0 commit comments

Comments
 (0)
Please sign in to comment.