Skip to content

Conversation

@TamaraFinogina
Copy link
Contributor

This PR adds functions needed for implementing Mail

@TamaraFinogina TamaraFinogina marked this pull request as ready for review January 21, 2026 17:24
@TamaraFinogina TamaraFinogina requested a review from sg-gs January 21, 2026 17:25
clientName: this.appDetails.clientName,
clientVersion: this.appDetails.clientVersion,
token: this.apiSecurity.token,
workspaceToken: this.apiSecurity.workspaceToken,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the workspaceToken or the desktopToken going to be needed for the meet server api?
If not, maybe its better to remove them from here 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I took this part from drive I think

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, copied headersWithToken from meet

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe they should be removed from there too haha

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@larryrider Fixed

@larryrider
Copy link
Contributor

If you are going to do a new release, remember to update the package.json version

*/
async decryptEmail(email: HybridEncryptedEmail, keys: EmailKeys): Promise<Email> {
const senderEmail = email.params.sender.email;
const pk = await this.getUserPublicKeys(senderEmail);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is pk and why it contains the publicKeys while other object (keys) contains the private ones? I feel this confusing unless the pk name is clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pk is the public key of the sender. To decrypt the email, we need both the public key of the person who sent the email and the private key of the receiver. I can rename pk to senderPublicKeys

*/
async getPublicKeysOfSeveralUsers(emails: string[]): Promise<UserWithPublicKeys[]> {
const response = await this.client.getWithParams<{ publicKeys: PublicKeysBase64; user: User }[]>(
`${this.apiUrl}/getPublicKeysOfSeveralUsers`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This path is not following REST. Something like /users/keys with a body would be better

*/
async getUserPublicKeys(userEmail: string): Promise<UserWithPublicKeys> {
const response = await this.client.getWithParams<{ publicKeys: PublicKeysBase64; user: User }>(
`${this.apiUrl}/getUserPublicKeys`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

* @returns Server response
*/
async uploadKeystoreToServer(encryptedKeystore: EncryptedKeystore): Promise<void> {
return this.client.post(`${this.apiUrl}/uploadKeystore`, { encryptedKeystore }, this.headers());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here:

POST /keys

Would be better

* @returns Server response
*/
async sendEncryptedEmail(email: HybridEncryptedEmail): Promise<void> {
return this.client.post(`${this.apiUrl}/sendEncryptedEmail`, { email }, this.headers());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

POST /mails

Would be more correct

* @returns Server response
*/
async sendEncryptedEmailToMultipleRecipients(emails: HybridEncryptedEmail[]): Promise<void> {
return this.client.post(`${this.apiUrl}/sendEncryptedEmailToMultipleRecipients`, { emails }, this.headers());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

* @returns Server response
*/
async sendPwdProtectedEmail(email: PwdProtectedEmail): Promise<void> {
return this.client.post(`${this.apiUrl}/sendPwdProtectedEmail`, { email }, this.headers());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

* @returns The encrypted keystore
*/
async downloadKeystoreFromServer(userEmail: string, keystoreType: KeystoreType): Promise<EncryptedKeystore> {
return this.client.getWithParams(`${this.apiUrl}/getKeystore`, { userEmail, keystoreType }, this.headers());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

GET /keys

@TamaraFinogina
Copy link
Contributor Author

@sg-gs I've changed the paths, now they are:

  • uploadKeystoreToServer → /keystore
  • downloadKeystoreFromServer → /user/keystore
  • getUserWithPublicKeys → /user/public-keys
  • getSeveralUsersWithPublicKeys → /users/public-keys
  • sendEncryptedEmail → /email/encrypted
  • sendEncryptedEmailToMultipleRecipients → /emails/encrypted
  • sendPasswordProtectedEmail → /email/password-protected
  1. I've used public-keys instead of keys because there are also private keys, and it might be confusing
  2. The email can be encrypted with Kyber + ECC or protected with a shared password, which results in different encrypted email types (HybridEncryptedEmail and PwdProtectedEmail) - hence 2 different post methods
  3. The email can be encrypted for several recipients, in which case the encrypted emails HybridEncryptedEmail are different for each recipient because recipientEmail and encryptedKey will be different based on who the exact recipient is, the rest of the HybridEncryptedEmail will be the same. I can adjust the type if necessary
 `HybridEncryptedEmail = {
    encryptedKey: HybridEncKey;
    enc: EmailBodyEncrypted;
    recipientEmail: string;
    params: EmailPublicParameters;
    id: string;
    isSubjectEncrypted: boolean;
}

@TamaraFinogina TamaraFinogina requested a review from sg-gs January 22, 2026 17:10
@sg-gs
Copy link
Member

sg-gs commented Jan 23, 2026

@sg-gs I've changed the paths, now they are:

  • uploadKeystoreToServer → /keystore
  • downloadKeystoreFromServer → /user/keystore
  • getUserWithPublicKeys → /user/public-keys
  • getSeveralUsersWithPublicKeys → /users/public-keys
  • sendEncryptedEmail → /email/encrypted
  • sendEncryptedEmailToMultipleRecipients → /emails/encrypted
  • sendPasswordProtectedEmail → /email/password-protected
  1. I've used public-keys instead of keys because there are also private keys, and it might be confusing
  2. The email can be encrypted with Kyber + ECC or protected with a shared password, which results in different encrypted email types (HybridEncryptedEmail and PwdProtectedEmail) - hence 2 different post methods
  3. The email can be encrypted for several recipients, in which case the encrypted emails HybridEncryptedEmail are different for each recipient because recipientEmail and encryptedKey will be different based on who the exact recipient is, the rest of the HybridEncryptedEmail will be the same. I can adjust the type if necessary
 `HybridEncryptedEmail = {
    encryptedKey: HybridEncKey;
    enc: EmailBodyEncrypted;
    recipientEmail: string;
    params: EmailPublicParameters;
    id: string;
    isSubjectEncrypted: boolean;
}

@TamaraFinogina
I see some potential improvements on the paths like entities should be always in plural and the duplication of EPs that should be under the same path. Thus I suggest you the following routes which I am pretty sure @jzunigax2 will almost agree:

  • uploadKeystoreToServer → POST /keystore
  • downloadKeystoreFromServer → GET /keystore
  • getUserWithPublicKeys → GET /users/public-keys?emails=<one_email_or_more>
  • getSeveralUsersWithPublicKeys → idem ⬆️
  • sendEncryptedEmail → POST /emails
  • sendEncryptedEmailToMultipleRecipients → idem ⬆️ (but different body)
  • sendPasswordProtectedEmail → idem ⬆️ (but different body)

Idea: Same action but additional params → same route (generally)

@jzunigax2
Copy link
Contributor

@sg-gs I've changed the paths, now they are:

  • uploadKeystoreToServer → /keystore
  • downloadKeystoreFromServer → /user/keystore
  • getUserWithPublicKeys → /user/public-keys
  • getSeveralUsersWithPublicKeys → /users/public-keys
  • sendEncryptedEmail → /email/encrypted
  • sendEncryptedEmailToMultipleRecipients → /emails/encrypted
  • sendPasswordProtectedEmail → /email/password-protected
  1. I've used public-keys instead of keys because there are also private keys, and it might be confusing
  2. The email can be encrypted with Kyber + ECC or protected with a shared password, which results in different encrypted email types (HybridEncryptedEmail and PwdProtectedEmail) - hence 2 different post methods
  3. The email can be encrypted for several recipients, in which case the encrypted emails HybridEncryptedEmail are different for each recipient because recipientEmail and encryptedKey will be different based on who the exact recipient is, the rest of the HybridEncryptedEmail will be the same. I can adjust the type if necessary
 `HybridEncryptedEmail = {
    encryptedKey: HybridEncKey;
    enc: EmailBodyEncrypted;
    recipientEmail: string;
    params: EmailPublicParameters;
    id: string;
    isSubjectEncrypted: boolean;
}

@TamaraFinogina I see some potential improvements on the paths like entities should be always in plural and the duplication of EPs that should be under the same path. Thus I suggest you the following routes which I am pretty sure @jzunigax2 will almost agree:

* uploadKeystoreToServer → POST /keystore

* downloadKeystoreFromServer → GET /keystore

* getUserWithPublicKeys → GET /users/public-keys?emails=<one_email_or_more>

* getSeveralUsersWithPublicKeys → idem ⬆️

* sendEncryptedEmail → POST /emails

* sendEncryptedEmailToMultipleRecipients → idem ⬆️ (but different body)

* sendPasswordProtectedEmail → idem ⬆️ (but different body)

Idea: Same action but additional params → same route (generally)

yeah agreed, only the get keys requests seem like a POST to me, so we avoid sending the emails in query params as I know there is a max url limit (though I have no clue how big or small this limit is) or avoid possiby exposing recipients in a server request log

@TamaraFinogina
Copy link
Contributor Author

@sg-gs @jzunigax2, functions now are the following:

  • uploadKeystoreToServer → /keystore
  • downloadKeystoreFromServer → /user/keystore
  • getUserWithPublicKeys →/users/public-keys with parameter emails: [userEmail]
  • getSeveralUsersWithPublicKeys → /users/public-keys with parameter emails
  • sendEncryptedEmail → /emails with parameter emails: [encryptedEmail]
  • sendEncryptedEmailToMultipleRecipients → /emails with parameter emails
  • sendPasswordProtectedEmail → /emails with parameter email

All of them are currently POST because getSeveralUsersWithPublicKeys and downloadKeystoreFromServer have user emails/email as parameters. I'm not sure we should expose them as part of the URL

P.S. I'm not sure if sendPasswordProtectedEmail should have emails, email, or something like pwd-email as input

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants