Skip to content
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

replace deprecated encryption method with web crypto builtin #284

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@ethereumjs/vm": "^5.9.0",
"@metamask/post-message-stream": "^6.1.2",
"@metamask/providers": "^11.1.1",
"@noble/secp256k1": "^1.7.1",
"@types/lodash": "^4.14.182",
"@types/sha256": "^0.2.0",
"@types/sprintf-js": "^1.1.2",
Expand Down
24 changes: 12 additions & 12 deletions src/app/account.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class AccountService {
return Object.keys(this.getPrivateUsers());
}

getEncryptedUsers(): { [key: string]: PublicUserInfo } {
async getEncryptedUsers(): Promise<{ [key: string]: PublicUserInfo }> {
const hostname = this.globalVars.hostname;
const privateUsers = this.getPrivateUsers();
const publicUsers: { [key: string]: PublicUserInfo } = {};
Expand All @@ -75,16 +75,17 @@ export class AccountService {
continue;
}

const encryptedSeedHex = this.cryptoService.encryptSeedHex(
const encryptedSeedHex = await this.cryptoService.encryptSeedHex(
privateUser.seedHex,
hostname
);
let encryptedMessagingKeyRandomness: string | undefined;
if (privateUser.messagingKeyRandomness) {
encryptedMessagingKeyRandomness = this.cryptoService.encryptSeedHex(
privateUser.messagingKeyRandomness,
hostname
);
encryptedMessagingKeyRandomness =
await this.cryptoService.encryptSeedHex(
privateUser.messagingKeyRandomness,
hostname
);
}
const accessLevelHmac = this.cryptoService.accessLevelHmac(
accessLevel,
Expand Down Expand Up @@ -1054,13 +1055,12 @@ export class AccountService {
);
}

encryptedSeedHexToPublicKeyBase58Check(encryptedSeedHex: string): string {
return this.seedHexToPublicKeyBase58Check(
this.cryptoService.decryptSeedHex(
encryptedSeedHex,
this.globalVars.hostname
)
async encryptedSeedHexToPublicKeyBase58Check(encryptedSeedHex: string) {
const seedHex = await this.cryptoService.decryptSeedHex(
encryptedSeedHex,
this.globalVars.hostname
);
return this.seedHexToPublicKeyBase58Check(seedHex);
}

seedHexToPublicKeyBase58Check(seedHex: string): string {
Expand Down
19 changes: 11 additions & 8 deletions src/app/approve/approve.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,30 @@ export class ApproveComponent implements OnInit {
this.finishFlow();
}

onSubmit(): void {
const user = this.accountService.getEncryptedUsers()[this.publicKey];
async onSubmit() {
const users = await this.accountService.getEncryptedUsers();
const user = users[this.publicKey];
const isDerived = this.accountService.isMetamaskAccount(user);
const seedHex = await this.seedHex();
const signedTransactionHex = this.signingService.signTransaction(
this.seedHex(),
seedHex,
this.transactionHex,
isDerived
);
this.finishFlow(signedTransactionHex);
}

finishFlow(signedTransactionHex?: string): void {
async finishFlow(signedTransactionHex?: string) {
const users = await this.accountService.getEncryptedUsers();
this.identityService.login({
users: this.accountService.getEncryptedUsers(),
users,
signedTransactionHex,
});
}

seedHex(): string {
const encryptedSeedHex =
this.accountService.getEncryptedUsers()[this.publicKey].encryptedSeedHex;
async seedHex() {
const users = await this.accountService.getEncryptedUsers();
const encryptedSeedHex = users[this.publicKey].encryptedSeedHex;
return this.cryptoService.decryptSeedHex(
encryptedSeedHex,
this.globalVars.hostname
Expand Down
5 changes: 3 additions & 2 deletions src/app/auth/google/google.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ export class GoogleComponent implements OnInit {
}
}

login(signedUp: boolean): void {
async login(signedUp: boolean) {
const users = await this.accountService.getEncryptedUsers();
this.identityService.login({
users: this.accountService.getEncryptedUsers(),
users,
publicKeyAdded: this.publicKey,
signedUp,
});
Expand Down
90 changes: 52 additions & 38 deletions src/app/backend-api.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { Observable, of, throwError, from } from 'rxjs';
import { catchError, map, switchMap } from 'rxjs/operators';
import { logInteractionEvent } from 'src/app/interaction-event-helpers';
import { environment } from '../environments/environment';
import { DerivedKey, Network, UserProfile } from '../types/identity';
Expand Down Expand Up @@ -291,25 +291,36 @@ export class BackendAPIService {
}

jwtPost(path: string, publicKey: string, body: any): Observable<any> {
const publicUserInfo = this.accountService.getEncryptedUsers()[publicKey];
// NOTE: there are some cases where derived user's were not being sent phone number
// verification texts due to missing public user info. This is to log how often
// this is happening.
logInteractionEvent('backend-api', 'jwt-post', {
hasPublicUserInfo: !!publicUserInfo,
});

if (!publicUserInfo) {
return of(null);
}
const isDerived = this.accountService.isMetamaskAccount(publicUserInfo);
return from(this.accountService.getEncryptedUsers()).pipe(
switchMap((users) => {
const publicUserInfo = users[publicKey];
// NOTE: there are some cases where derived user's were not being sent phone number
// verification texts due to missing public user info. This is to log how often
// this is happening.
logInteractionEvent('backend-api', 'jwt-post', {
hasPublicUserInfo: !!publicUserInfo,
});

if (!publicUserInfo) {
return of(null);
}

const seedHex = this.cryptoService.decryptSeedHex(
publicUserInfo.encryptedSeedHex,
this.globalVars.hostname
// TODO: this will need to be async as well...
return from(
this.cryptoService.decryptSeedHex(
publicUserInfo.encryptedSeedHex,
this.globalVars.hostname
)
).pipe(
switchMap((seedHex) => {
const isDerived =
this.accountService.isMetamaskAccount(publicUserInfo);
const jwt = this.signingService.signJWT(seedHex, isDerived);
return this.post(path, { ...body, ...{ JWT: jwt } });
})
);
})
);
const jwt = this.signingService.signJWT(seedHex, isDerived);
return this.post(path, { ...body, ...{ JWT: jwt } });
}

// Error parsing
Expand Down Expand Up @@ -704,25 +715,28 @@ export class BackendAPIService {
Broadcast: boolean
): Observable<any> {
// Check if the user is logged in with a derived key and operating as the owner key.
const DerivedPublicKeyBase58Check =
this.accountService.getEncryptedUsers()[PublicKeyBase58Check]
?.derivedPublicKeyBase58Check;

const req = this.post('exchange-bitcoin', {
PublicKeyBase58Check,
DerivedPublicKeyBase58Check,
BurnAmountSatoshis,
LatestBitcionAPIResponse,
BTCDepositAddress,
FeeRateSatoshisPerKB,
SignedHashes,
Broadcast,
});

return req.pipe(
catchError((err) => {
console.error(JSON.stringify(err));
return throwError(err);
return from(this.accountService.getEncryptedUsers()).pipe(
switchMap((users) => {
const DerivedPublicKeyBase58Check =
users[PublicKeyBase58Check]?.derivedPublicKeyBase58Check;

const req = this.post('exchange-bitcoin', {
PublicKeyBase58Check,
DerivedPublicKeyBase58Check,
BurnAmountSatoshis,
LatestBitcionAPIResponse,
BTCDepositAddress,
FeeRateSatoshisPerKB,
SignedHashes,
Broadcast,
});

return req.pipe(
catchError((err) => {
console.error(JSON.stringify(err));
return throwError(err);
})
);
})
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ export class BuyDeSoCompleteComponent implements OnInit {
this.buyMoreDeSoClicked.emit();
}

close(): void {
async close() {
this.closeModal.emit();
const users = await this.accountService.getEncryptedUsers();
this.identityService.login({
users: this.accountService.getEncryptedUsers(),
users,
publicKeyAdded: this.publicKey,
signedUp: this.globalVars.signedUp,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ export class BuyDeSoHeroSwapComponent implements OnInit, OnDestroy {
}
}

login(): void {
async login() {
const users = await this.accountService.getEncryptedUsers();
this.identityService.login({
users: this.accountService.getEncryptedUsers(),
users,
publicKeyAdded: this.publicKey,
signedUp: this.globalVars.signedUp,
});
Expand Down
8 changes: 4 additions & 4 deletions src/app/buy-deso/buy-deso/buy-deso.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,16 @@ export class BuyDeSoComponent implements OnInit {
);
}

ngOnInit(): void {
const encryptedUser =
this.accountService.getEncryptedUsers()[this.publicKey];
async ngOnInit() {
const users = await this.accountService.getEncryptedUsers();
const encryptedUser = users[this.publicKey];
// TODO: need some sort of UI for when we can't get encrypted user.
if (!encryptedUser) {
console.error('Encrypted User not found: Buying DESO will not work.');
this.publicKeyNotInIdentity = true;
return;
} else {
this.seedHex = this.cryptoService.decryptSeedHex(
this.seedHex = await this.cryptoService.decryptSeedHex(
encryptedUser.encryptedSeedHex,
this.globalVars.hostname
);
Expand Down
5 changes: 3 additions & 2 deletions src/app/buy-or-send-deso/buy-or-send-deso.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,10 @@ export class BuyOrSendDesoComponent implements OnInit {
}
}

login(): void {
async login() {
const users = await this.accountService.getEncryptedUsers();
this.identityService.login({
users: this.accountService.getEncryptedUsers(),
users,
publicKeyAdded: this.publicKeyAdded,
signedUp: this.globalVars.signedUp,
});
Expand Down
Loading