Skip to content

Commit

Permalink
Add a backup component
Browse files Browse the repository at this point in the history
- This is not how the final version will be, it's a test of various export methods.
- We will implement encrypted storage of recovery phrase.
  • Loading branch information
sondreb committed Jun 27, 2024
1 parent 20d104e commit 33f484d
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 1 deletion.
55 changes: 55 additions & 0 deletions app/src/app/account/backup/backup.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<h1>Backup your account</h1>


<p>
<button mat-flat-button (click)="backupToFile()">
<mat-icon>save</mat-icon>
Save to file (without password)
</button>

<button mat-flat-button (click)="backupToProtectedFile()">
<mat-icon>save_as</mat-icon>
Save to file (with password)
</button>

<button mat-flat-button>
<mat-icon>groups</mat-icon>
Social Recovery Setup (3 friends)
</button>

<button mat-flat-button>
<mat-icon>backup</mat-icon>
Save to Cloud
</button>

</p>

<mat-card>
<mat-card-content>


<p>Ariton is unique and unlike other apps you are used to. Ariton is self-custodial, meaning that you are responsible for keeping your
account safe and secure. If you lose your account, you lose all your data and access to the app.
</p>
<p>
To prevent this, you can take a backup of your account. This backup is encrypted and can be used to restore your account on other devices.
</p>
<p>Additionally we believe in giving you amazing user experience, so we have different options to choose from when it comes to backup.</p>

<p>Quick explaination:</p>

<ul>

<li>You can save your account to a file on your local device. If anyone get hold of this file, they can access your account.</li>

<li>Save to your local device with password protection. This makes the file encrypted with your password, making it much harder for someone to access yoru account, even if they get a copy of your backup file.</li>

<li>Social backup is a unique feature that less apps have today. It allows you to choose 3 of your friends that you trust. If you ever loose your account (or device), you can simply ask your 3 friends to help restore your account. This must be setup before it can be used and you friends has to accept this responsibility.</li>

<li>We also support backup using cloud storage, this is less secure than other options, but it's convenient to use as you can access your account as long as you can access your cloud storage. We plan to support OneDrive (Microsoft), Google Drive, iCloud (Apple)</li>

</ul>

<p>You can of course use multiple options.</p>
</mat-card-content>
</mat-card>
4 changes: 4 additions & 0 deletions app/src/app/account/backup/backup.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
button {
margin-top: 1em;
margin-right: 1em;
}
23 changes: 23 additions & 0 deletions app/src/app/account/backup/backup.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { BackupComponent } from './backup.component';

describe('BackupComponent', () => {
let component: BackupComponent;
let fixture: ComponentFixture<BackupComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [BackupComponent]
})
.compileComponents();

fixture = TestBed.createComponent(BackupComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
46 changes: 46 additions & 0 deletions app/src/app/account/backup/backup.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { IdentityService } from '../../identity.service';
import { Web5IdentityAgent } from '@web5/identity-agent';

@Component({
selector: 'app-backup',
standalone: true,
imports: [MatButtonModule, MatIconModule, MatCardModule],
templateUrl: './backup.component.html',
styleUrl: './backup.component.scss'
})
export class BackupComponent {

constructor(private identityService: IdentityService) { }

async backupToFile() {
const portableDid = await this.identityService.activeAgent().vault.backup();
const data = portableDid.data; // Assuming portableDid is the string you want to save
await this.saveFile(data);
}

async saveFile(data: string) {

const blob = new Blob([data], { type: 'text/plain' });
const url = window.URL.createObjectURL(blob);

const a = document.createElement('a');
a.href = url;
a.download = 'ariton-account-backup.txt'; // Suggest a filename for the download
document.body.appendChild(a); // Append the anchor to the body to make it clickable
a.click(); // Programmatically click the anchor to trigger the download

window.URL.revokeObjectURL(url); // Clean up by revoking the Blob URL
a.remove(); // Remove the anchor from the document
}

async backupToProtectedFile () {
const portableDid = await this.identityService.activeAgent().agentDid.export();
console.log(portableDid);
const data = JSON.stringify(portableDid); // Assuming portableDid is the string you want to save
await this.saveFile(data);
}
}
7 changes: 7 additions & 0 deletions app/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ export const routes: Routes = [
title: 'Password',
data: { hide: true, icon: 'account_circle' },
},
{
path: 'account/backup',
loadComponent: () =>
import('./account/backup/backup.component').then((c) => c.BackupComponent),
title: 'Backup',
data: { hide: true, icon: 'account_circle' },
},
{
path: 'account/create',
loadComponent: () =>
Expand Down
5 changes: 5 additions & 0 deletions app/src/app/identity.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ export class IdentityService {
});
}

activeAgent() {
const agent = this.web5.agent as Web5IdentityAgent;
return agent;
}

async changePassword(oldPassword: string, newPassword: string) {
const agent = this.web5.agent as Web5IdentityAgent;
await agent.vault.changePassword({ oldPassword, newPassword });
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/introduction/introduction.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ <h1>Welcome</h1>
<p>
<button mat-stroked-button [routerLink]="['/communities']">Skip and jump into the app</button>
<button mat-flat-button [routerLink]="['/account/password']">Set a secure password</button>
<button mat-flat-button>Backup your account</button>
<button mat-flat-button [routerLink]="['/account/backup']">Backup your account</button>
</p>

<mat-divider></mat-divider>
Expand Down

0 comments on commit 33f484d

Please sign in to comment.