Skip to content

Commit

Permalink
prepare migration infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
jlcvp committed Sep 20, 2024
1 parent e7da789 commit 49352ff
Show file tree
Hide file tree
Showing 19 changed files with 385 additions and 45 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"root": true,
"ignorePatterns": ["projects/**/*"],
"env": {
"es6": true
},
"overrides": [
{
"files": ["*.ts"],
Expand Down
92 changes: 90 additions & 2 deletions package-lock.json

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

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"prebuild": "npm run version:config",
"build": "ng build",
"build:githubpages": "ng build --configuration githubpages --base-href ./",
"watch": "ng build --watch --configuration development",
Expand All @@ -15,7 +16,8 @@
"translations:check": "node ./resources/scripts/translations_complete_check.js",
"firebase:deploy:firestore:indexes": "firebase deploy --only firestore:indexes",
"firebase:deploy:hosting": "ng build --prod && firebase deploy --only hosting",
"firebase:deploy:all": "ng build --prod && firebase deploy"
"firebase:deploy:all": "ng build --prod && firebase deploy",
"version:config": "node ./resources/scripts/version-config.js"
},
"private": true,
"dependencies": {
Expand Down Expand Up @@ -72,6 +74,7 @@
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"replace-in-file": "^6.3.5",
"typescript": "~5.4.0"
}
}
21 changes: 21 additions & 0 deletions resources/scripts/version-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node

const replacer = require('replace-in-file')
const package = require('../../package.json')

const buildDate = new Date().toISOString()
// get git commit hash from GITHUB_SHA environment variable
const commitHash = process.env.GITHUB_SHA || 'unknown'

const options = {
files: 'src/environments/environment*.ts',
from: [/%VERSION%/g, /%BUILD_DATE%/g, /%COMMIT_HASH%/g],
to: [package.version, buildDate, commitHash],
}

try {
const changes = replacer.sync(options)
console.log('Modified files:', JSON.stringify(changes, null, 2))
} catch (error) {
console.error('Error replacing version strings occurred:', error)
}
34 changes: 26 additions & 8 deletions src/app/home/home.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@
<ion-button (click)="showPopover($event)">
<ion-icon slot="icon-only" name="settings-outline"></ion-icon>
</ion-button>
<ion-popover #popover [isOpen]="isPopoverOpen" triggerAction="click" [dismissOnSelect]="true">
<ion-popover #popover [isOpen]="isPopoverOpen" triggerAction="click" [dismissOnSelect]="true" class="wider-popover">
<ng-template>
<ion-content>
<ion-list class="ion-no-padding">

<ion-item button detail="false" (click)="lockAccountAction()">
<ion-icon slot="start" name="lock-closed-outline"></ion-icon>
<ion-label>{{ "CONFIG_MENU.LOCK" | translate }}</ion-label>
</ion-item>
<ion-item button detail="false" (click)="unlockAccountAction()">
<ion-icon slot="start" name="lock-open-outline"></ion-icon>
<ion-label>{{ "CONFIG_MENU.UNLOCK" | translate }}</ion-label>
Expand All @@ -30,12 +25,35 @@
<ion-icon slot="start" name="download-outline"></ion-icon>
<ion-label>{{ "CONFIG_MENU.IMPORT_ACCOUNTS" | translate }}</ion-label>
</ion-item>
<ion-item button id="dark-mode-trigger">
<ion-item button detail="true" id="encryption-menu-trigger">
<ion-icon slot="start" name="document-lock-outline"></ion-icon>
<ion-label>{{ "CONFIG_MENU.ENCRYPTION_OPTIONS" | translate }}</ion-label>
<ion-note slot="end" [color]="encryptionMenuSlotLabelColor">{{ encryptionMenuSlotLabel | translate }}</ion-note>
</ion-item>
<ion-popover trigger="encryption-menu-trigger" class="wider-popover" reference="event">
<ng-template>
<ion-content>
<ion-list>
<ion-item button detail="false" (click)="encryptionActiveToggle()">
<ion-toggle color="success" [checked]="isEncryptionActive"> {{ "CONFIG_MENU.ENCRYPT_ACCOUNTS" | translate }} </ion-toggle>
</ion-item>
<ion-item button detail="false" (click)="periodicCheckToggle()">
<ion-toggle [checked]="shouldPeriodicCheckPassword"> {{ "CONFIG_MENU.PERIODIC_CHECK" | translate }} </ion-toggle>
</ion-item>
<!-- <ion-item button detail="false" (click)="changeEncryptionAction('password')">
<ion-icon slot="start" ></ion-icon>
<ion-label>{{ "CONFIG_MENU.ENCRYPTION_PASSWORD" | translate }}</ion-label>
</ion-item> -->
</ion-list>
</ion-content>
</ng-template>
</ion-popover>
<ion-item button detail="true" id="dark-mode-trigger">
<ion-icon slot="start" name="invert-mode-outline"></ion-icon>
<ion-label> {{ "CONFIG_MENU.COLOR_MODE" | translate }} </ion-label>
<ion-note slot="end">{{ darkModeLabel | translate }}</ion-note>
</ion-item>
<ion-popover trigger="dark-mode-trigger" [dismissOnSelect]="true" side="end">
<ion-popover trigger="dark-mode-trigger" [dismissOnSelect]="true" reference="event">
<ng-template>
<ion-content>
<ion-list>
Expand Down
110 changes: 101 additions & 9 deletions src/app/home/home.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { LocalStorageService } from '../services/local-storage.service';
import { TranslateService } from '@ngx-translate/core';
import { GlobalUtils } from '../utils/global-utils';
import { AccountSelectModalComponent } from '../components/account-select-modal/account-select-modal.component';
import { AppConfigService } from '../services/app-config.service';
import { ENCRYPTION_OPTIONS_PASSWORD_KEY, EncryptionOptions } from '../models/encryption-options.model';

@Component({
selector: 'app-home',
Expand Down Expand Up @@ -63,6 +65,8 @@ export class HomePage implements OnInit {
isAddAccountModalOpen: boolean = false
isScanActive: boolean = false
isWindowFocused: boolean = true
isEncryptionActive: boolean = false
shouldPeriodicCheckPassword: boolean = false

private systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)');
private isLandscape: boolean = false
Expand All @@ -77,6 +81,7 @@ export class HomePage implements OnInit {
private modalController: ModalController,
private logoService: LogoService,
private storageService: LocalStorageService,
private configService: AppConfigService,
private translateService: TranslateService,
private navCtrl: NavController,
formBuilder: FormBuilder
Expand Down Expand Up @@ -132,16 +137,12 @@ export class HomePage implements OnInit {
backdropDismiss: false
})
GlobalUtils.hideSplashScreen()
await loading.present()
this.accounts$ = await this.accountsService.getAccounts()
const lastSelectedAccountId: string | undefined = await this.storageService.get('lastSelectedAccountId')
if (lastSelectedAccountId) {
const accounts = await firstValueFrom(this.accounts$)
const lastSelectedAccount = accounts.find(account => account.id === lastSelectedAccountId)
if (lastSelectedAccount) {
this.selectAccount(lastSelectedAccount)
}
const encryptionOptions = await this.configService.getEncryptionOptions()
if(encryptionOptions) {
await this.setupEncryption(encryptionOptions)
}
await loading.present()
await this.loadAccounts()
await loading.dismiss()
}

Expand Down Expand Up @@ -309,6 +310,30 @@ export class HomePage implements OnInit {
}
}

async encryptionActiveToggle() {
this.isEncryptionActive = !this.isEncryptionActive
await this.saveEncryptionOptions()
}

get encryptionMenuSlotLabel(): string {
return this.isEncryptionActive ? 'CONFIG_MENU.ENCRYPTION_ACTIVE' : 'CONFIG_MENU.ENCRYPTION_INACTIVE'
}

get encryptionMenuSlotLabelColor(): string {
return this.isEncryptionActive ? 'success' : 'danger'
}

periodicCheckToggle() {
this.shouldPeriodicCheckPassword = !this.shouldPeriodicCheckPassword
}

async saveEncryptionOptions() {
await this.configService.setEncryptionOptions({
encryptionActive: this.isEncryptionActive,
shouldPerformPeriodicCheck: this.shouldPeriodicCheckPassword
})
}

async lockAccountAction() {
const password = '1490'
const accountSelected = this.selectedAccount
Expand Down Expand Up @@ -592,4 +617,71 @@ export class HomePage implements OnInit {
await confirmPrompt.present()
})
}

private async loadAccounts() {
const accounts$ = await this.accountsService.getAccounts()
const lastSelectedAccountId: string | undefined = await this.storageService.get('lastSelectedAccountId')
if (lastSelectedAccountId) {
const accounts = await firstValueFrom(accounts$)
const lastSelectedAccount = accounts.find(account => account.id === lastSelectedAccountId)
if (lastSelectedAccount) {
this.selectAccount(lastSelectedAccount)
}
}
this.accounts$ = accounts$
}

private async setupEncryption(encryptionOptions: EncryptionOptions) {
// set page properties
this.isEncryptionActive = encryptionOptions.encryptionActive
this.shouldPeriodicCheckPassword = encryptionOptions.shouldPerformPeriodicCheck

if(this.isEncryptionActive) {
await this.setupEncryptionPassword()
}
}

private async setupEncryptionPassword() {
const password = await this.storageService.get<string>(ENCRYPTION_OPTIONS_PASSWORD_KEY)
if(!password) {
// show password prompt
const password = await this.promptPassword()
if(password) {
await this.storageService.set(ENCRYPTION_OPTIONS_PASSWORD_KEY, password)
}
}
}

private async promptPassword(): Promise<string> {
const title = await firstValueFrom(this.translateService.get('HOME.PASSWORD_PROMPT_TITLE'))
const message = await firstValueFrom(this.translateService.get('HOME.PASSWORD_PROMPT_MESSAGE'))
const cancelText = await firstValueFrom(this.translateService.get('HOME.PASSWORD_PROMPT_CANCEL'))
const okText = await firstValueFrom(this.translateService.get('HOME.PASSWORD_PROMPT_CONFIRM'))

const alert = await this.alertController.create({
header: title,
message,
inputs: [
{
name: 'password',
type: 'password'
}
],
buttons: [
{
text: cancelText,
role: 'cancel'
}, {
text: okText,
handler: (data) => {
return data.password
}
}
]
})
await alert.present()

const { data } = await alert.onDidDismiss()
return data?.values?.password || ''
}
}
1 change: 1 addition & 0 deletions src/app/models/account2FA.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface IAccount2FA {
export interface IAccount2FAProvider {
getAccounts(): Promise<Observable<Account2FA[]>>;
addAccount(account: Account2FA): Promise<string>;
updateAccount(account: Account2FA): Promise<void>;
clearCache?(): Promise<void>;
}

Expand Down
7 changes: 7 additions & 0 deletions src/app/models/encryption-options.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface EncryptionOptions {
encryptionActive: boolean;
shouldPerformPeriodicCheck: boolean;
}

export const ENCRYPTION_OPTIONS_KEY = 'encryptionOptions';
export const ENCRYPTION_OPTIONS_PASSWORD_KEY = '_eok';
Loading

0 comments on commit 49352ff

Please sign in to comment.