Skip to content

Commit

Permalink
reduce API diff to maintain compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
overheadhunter committed May 30, 2024
1 parent 3ca5238 commit 99f4e15
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public record DeviceDto(@JsonProperty("id") @ValidId String id,
@JsonProperty("name") @NoHtmlOrScriptChars @NotBlank String name,
@JsonProperty("type") Device.Type type,
@JsonProperty("publicKey") @NotNull @OnlyBase64Chars String publicKey,
@JsonProperty("userPrivateKeys") @NotNull @ValidJWE String userPrivateKeys,
@JsonProperty("userPrivateKey") @NotNull @ValidJWE String userPrivateKeys, // singular name for history reasons (don't break client compatibility)
@JsonProperty("owner") @ValidId String ownerId,
@JsonProperty("creationTime") Instant creationTime) {

Expand Down
9 changes: 8 additions & 1 deletion backend/src/main/java/org/cryptomator/hub/api/UserDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ public final class UserDto extends AuthorityDto {
public final String ecdhPublicKey;
@JsonProperty("ecdsaPublicKey")
public final String ecdsaPublicKey;
@JsonProperty("privateKeys")
@JsonProperty("privateKey") // singular name for history reasons (don't break client compatibility)
public final String privateKeys;
@JsonProperty("setupCode")
public final String setupCode;

@Deprecated
@JsonProperty("publicKey")
public final String legacyEcdhPublicKey;

UserDto(@JsonProperty("id") String id, @JsonProperty("name") String name, @JsonProperty("pictureUrl") String pictureUrl, @JsonProperty("email") String email, @JsonProperty("devices") Set<DeviceResource.DeviceDto> devices,
@Nullable @JsonProperty("ecdhPublicKey") @OnlyBase64Chars String ecdhPublicKey, @Nullable @JsonProperty("ecdsaPublicKey") @OnlyBase64Chars String ecdsaPublicKey, @Nullable @JsonProperty("privateKeys") @ValidJWE String privateKeys, @Nullable @JsonProperty("setupCode") @ValidJWE String setupCode) {
super(id, Type.USER, name, pictureUrl);
Expand All @@ -32,6 +36,9 @@ public final class UserDto extends AuthorityDto {
this.ecdsaPublicKey = ecdsaPublicKey;
this.privateKeys = privateKeys;
this.setupCode = setupCode;

// duplicate fields to maintain backwards compatibility:
this.legacyEcdhPublicKey = ecdhPublicKey;
}

public static UserDto justPublicInfo(User user) {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/common/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export type DeviceDto = {
name: string;
type: 'BROWSER' | 'DESKTOP' | 'MOBILE';
publicKey: string;
userPrivateKeys: string;
userPrivateKey: string;
creationTime: Date;
};

Expand All @@ -74,7 +74,7 @@ export type UserDto = {
accessibleVaults: VaultDto[];
ecdhPublicKey?: string;
ecdsaPublicKey?: string;
privateKeys?: string;
privateKey?: string;
setupCode?: string;
}

Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/InitialSetup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ async function createUserKey() {
const userKeys = await UserKeys.create();
me.value.ecdhPublicKey = await userKeys.encodedEcdhPublicKey();
me.value.ecdsaPublicKey = await userKeys.encodedEcdsaPublicKey();
me.value.privateKeys = await userKeys.encryptWithSetupCode(setupCode.value);
me.value.privateKey = await userKeys.encryptWithSetupCode(setupCode.value);
me.value.setupCode = await JWEBuilder.ecdhEs(userKeys.ecdhKeyPair.publicKey).encrypt({ setupCode: setupCode.value });
const browserKeys = await createBrowserKeys(me.value.id);
await submitBrowserKeys(browserKeys, me.value, userKeys);
Expand All @@ -284,14 +284,14 @@ async function createUserKey() {
async function recoverUserKey() {
onRecoverError.value = null;
try {
if (!me.value || !me.value.ecdhPublicKey || !me.value.ecdsaPublicKey || !me.value.privateKeys) {
if (!me.value || !me.value.ecdhPublicKey || !me.value.ecdsaPublicKey || !me.value.privateKey) {
throw new Error('Invalid state');
}
processing.value = true;
const ecdhPublicKey = base64.parse(me.value.ecdhPublicKey);
const ecdsaPublicKey = me.value.ecdsaPublicKey ? base64.parse(me.value.ecdsaPublicKey) : undefined;
const userKeys = await UserKeys.recover(me.value.privateKeys, setupCode.value, ecdhPublicKey, ecdsaPublicKey);
const userKeys = await UserKeys.recover(me.value.privateKey, setupCode.value, ecdhPublicKey, ecdsaPublicKey);
const browserKeys = await createBrowserKeys(me.value.id);
await submitBrowserKeys(browserKeys, me.value, userKeys);
Expand All @@ -317,7 +317,7 @@ async function submitBrowserKeys(browserKeys: BrowserKeys, me: UserDto, userKeys
name: deviceName.value,
type: 'BROWSER',
publicKey: await browserKeys.encodedPublicKey(),
userPrivateKeys: jwe,
userPrivateKey: jwe,
creationTime: new Date()
});
await backend.users.putMe(me);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ManageSetupCode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ async function fetchData() {
if (myDevice == null) {
throw new Error('Device not initialized.');
}
const userKeys = await UserKeys.decryptOnBrowser(myDevice.userPrivateKeys, browserKeys.keyPair.privateKey, base64.parse(me.ecdhPublicKey), base64.parse(me.ecdsaPublicKey));
const userKeys = await UserKeys.decryptOnBrowser(myDevice.userPrivateKey, browserKeys.keyPair.privateKey, base64.parse(me.ecdhPublicKey), base64.parse(me.ecdsaPublicKey));
const payload : { setupCode: string } = await JWEParser.parse(me.setupCode).decryptEcdhEs(userKeys.ecdhKeyPair.privateKey);
setupCode.value = payload.setupCode;
} catch (error) {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/RegenerateSetupCodeDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ async function regenerateSetupCode() {
throw new Error('Device not initialized.');
}
const newCode = crypto.randomUUID();
const userKeys = await UserKeys.decryptOnBrowser(myDevice.userPrivateKeys, browserKeys.keyPair.privateKey, base64.parse(me.ecdhPublicKey), base64.parse(me.ecdsaPublicKey));
me.privateKeys = await userKeys.encryptWithSetupCode(newCode);
const userKeys = await UserKeys.decryptOnBrowser(myDevice.userPrivateKey, browserKeys.keyPair.privateKey, base64.parse(me.ecdhPublicKey), base64.parse(me.ecdsaPublicKey));
me.privateKey = await userKeys.encryptWithSetupCode(newCode);
me.setupCode = await JWEBuilder.ecdhEs(userKeys.ecdhKeyPair.publicKey).encrypt({ setupCode: newCode });
await backend.users.putMe(me);
setupCode.value = newCode;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VaultDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ async function loadVaultKeys(vaultKeyJwe: string): Promise<VaultKeys> {
if (myDevice == null) {
throw new Error('Device not initialized.');
}
const userKeys = await UserKeys.decryptOnBrowser(myDevice.userPrivateKeys, browserKeys.keyPair.privateKey, base64.parse(me.value.ecdhPublicKey), base64.parse(me.value.ecdsaPublicKey));
const userKeys = await UserKeys.decryptOnBrowser(myDevice.userPrivateKey, browserKeys.keyPair.privateKey, base64.parse(me.value.ecdhPublicKey), base64.parse(me.value.ecdsaPublicKey));
return VaultKeys.decryptWithUserKey(vaultKeyJwe, userKeys.ecdhKeyPair.privateKey);
}
Expand Down

0 comments on commit 99f4e15

Please sign in to comment.