-
-
Notifications
You must be signed in to change notification settings - Fork 21
Fix key attachment bug and add dual-key support #1316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,10 +59,24 @@ export class KnexAccountRepository { | |
| ap_outbox_url: draft.apOutbox?.href ?? null, | ||
| ap_following_url: draft.apFollowing?.href ?? null, | ||
| ap_liked_url: draft.apLiked?.href ?? null, | ||
| ap_public_key: JSON.stringify( | ||
| await exportJwk(draft.apPublicKey), | ||
| ), | ||
| ap_private_key: draft.apPrivateKey | ||
| ap_public_key: (draft as any).dualKeyPairs | ||
| ? JSON.stringify({ | ||
| keys: await Promise.all( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't love the idea of storing two different data types in the same column here. I think we need a discussion about either:
|
||
| (draft as any).dualKeyPairs.map((kp: { publicKey: CryptoKey, privateKey: CryptoKey }) => | ||
| exportJwk(kp.publicKey) | ||
| ) | ||
| ) | ||
| }) | ||
| : JSON.stringify(await exportJwk(draft.apPublicKey)), | ||
| ap_private_key: (draft as any).dualKeyPairs | ||
| ? JSON.stringify({ | ||
| keys: await Promise.all( | ||
| (draft as any).dualKeyPairs.map((kp: { publicKey: CryptoKey, privateKey: CryptoKey }) => | ||
| exportJwk(kp.privateKey) | ||
| ) | ||
| ) | ||
| }) | ||
| : draft.apPrivateKey | ||
| ? JSON.stringify(await exportJwk(draft.apPrivateKey)) | ||
| : null, | ||
| custom_fields: draft.customFields | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,7 +64,12 @@ export class AccountService { | |
| private readonly events: AsyncEvents, | ||
| private readonly accountRepository: KnexAccountRepository, | ||
| private readonly fedifyContextFactory: FedifyContextFactory, | ||
| private readonly generateKeyPair: () => Promise<CryptoKeyPair> = generateCryptoKeyPair, | ||
| private readonly generateKeyPair: () => Promise<{ publicKey: CryptoKey, privateKey: CryptoKey }[]> = async () => { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method name needs updating to reflect the new return type (singular -> plural). Why have we stopped using the |
||
| // Generate both Ed25519 and RSA for maximum compatibility | ||
| const ed25519Keys = await generateCryptoKeyPair('Ed25519'); | ||
| const rsaKeys = await generateCryptoKeyPair('RSASSA-PKCS1-v1_5'); | ||
| return [ed25519Keys, rsaKeys]; | ||
| }, | ||
| ) {} | ||
|
|
||
| /** | ||
|
|
@@ -178,7 +183,7 @@ export class AccountService { | |
| site: Site, | ||
| internalAccountData: InternalAccountData, | ||
| ): Promise<AccountType> { | ||
| const keyPair = await this.generateKeyPair(); | ||
| const keyPairs = await this.generateKeyPair(); | ||
|
|
||
| const normalizedHost = site.host.replace(/^www\./, ''); | ||
|
|
||
|
|
@@ -192,10 +197,13 @@ export class AccountService { | |
| avatarUrl: parseURL(internalAccountData.avatar_url), | ||
| bannerImageUrl: parseURL(internalAccountData.banner_image_url), | ||
| customFields: null, | ||
| apPublicKey: keyPair.publicKey, | ||
| apPrivateKey: keyPair.privateKey, | ||
| apPublicKey: keyPairs[0].publicKey, | ||
| apPrivateKey: keyPairs[0].privateKey, | ||
| }); | ||
|
|
||
| // Attach dual keys for repository to handle | ||
| (draft as any).dualKeyPairs = keyPairs; | ||
|
|
||
| try { | ||
| const account = await this.accountRepository.create(draft); | ||
| const returnVal = await this.getByInternalId(account.id); | ||
|
|
@@ -241,18 +249,22 @@ export class AccountService { | |
| )?.ap_private_key; | ||
|
|
||
| if (!hasPrivateKey) { | ||
| const newKeyPair = await this.generateKeyPair(); | ||
| const newKeyPairs = await this.generateKeyPair(); | ||
| await this.db('accounts') | ||
| .where({ | ||
| id: existingAccount.id, | ||
| }) | ||
| .update({ | ||
| ap_public_key: JSON.stringify( | ||
| await exportJwk(newKeyPair.publicKey), | ||
| ), | ||
| ap_private_key: JSON.stringify( | ||
| await exportJwk(newKeyPair.privateKey), | ||
| ), | ||
| ap_public_key: JSON.stringify({ | ||
| keys: await Promise.all( | ||
| newKeyPairs.map(kp => exportJwk(kp.publicKey)) | ||
| ) | ||
| }), | ||
| ap_private_key: JSON.stringify({ | ||
| keys: await Promise.all( | ||
| newKeyPairs.map(kp => exportJwk(kp.privateKey)) | ||
| ) | ||
| }), | ||
| }); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,17 @@ | ||
| import { generateCryptoKeyPair } from '@fedify/fedify'; | ||
|
|
||
| let cachedKeyPair: Promise<CryptoKeyPair> | null = null; | ||
| let cachedKeyPairs: Promise<CryptoKeyPair[]> | null = null; | ||
|
|
||
| export async function generateTestCryptoKeyPair() { | ||
| if (cachedKeyPair !== null) { | ||
| return cachedKeyPair; | ||
| if (cachedKeyPairs !== null) { | ||
| return cachedKeyPairs; | ||
| } | ||
|
|
||
| cachedKeyPair = generateCryptoKeyPair(); | ||
| cachedKeyPairs = (async () => { | ||
| const ed25519Keys = await generateCryptoKeyPair('Ed25519'); | ||
| const rsaKeys = await generateCryptoKeyPair('RSASSA-PKCS1-v1_5'); | ||
| return [ed25519Keys, rsaKeys]; | ||
| })(); | ||
|
|
||
| return cachedKeyPair; | ||
| return cachedKeyPairs; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't be casting to
anyhere, the draft type should be updated