Skip to content

Commit

Permalink
Merge pull request #19 from josh-gaby/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
josh-gaby authored Aug 18, 2024
2 parents 65a6b56 + 4fcb247 commit f794fa3
Show file tree
Hide file tree
Showing 42 changed files with 2,435 additions and 2,218 deletions.
16 changes: 15 additions & 1 deletion bump-version.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
#!/usr/bin/env node
const parseArgs = (args) => {
const parsedArgs = {};
args.forEach((arg) => {
const parts = arg.split("=");
parsedArgs[parts[0]] = parts[1];
});

return parsedArgs;
};

const args = parseArgs(process.argv.slice(2));

const { writeFile, readFile, readFileSync } = require('fs');
const pkg = JSON.parse(readFileSync('./package.json')),
Expand All @@ -16,7 +27,10 @@ if (major_minor !== `${major}.${minor}`) {
patch++;
}

const new_version = `${major_minor}.${patch}`;
let new_version = `${major_minor}.${patch}`;
if (args.setPrefix) {
new_version += `.${args.setPrefix}`
}

console.log('Updating version: ', current_version, '=>', new_version);

Expand Down
3,145 changes: 1,463 additions & 1,682 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "2fauth-chrome",
"version": "2024.3.3",
"version": "2024.7.1",
"scripts": {
"ng": "ng",
"build:chrome": "ng build -c development,chrome",
Expand All @@ -10,8 +10,8 @@
"dist:chrome": "ng build -c production,chrome,chrome-dist",
"dist:firefox": "ng build -c production,firefox,firefox-dist",
"dist": "npm run dist:chrome && npm run dist:firefox",
"package:firefox": "web-ext build -s ./dist/2fauth-firefox -a ./dist/packaged/firefox -o true",
"package:chrome": "web-ext build -s ./dist/2fauth-chrome -a ./dist/packaged/chrome -o true",
"package:firefox": "web-ext build -s ./dist/2fauth-firefox -a ./dist/packaged/firefox -n {name}-{version}-firefox.zip -o true",
"package:chrome": "web-ext build -s ./dist/2fauth-chrome -a ./dist/packaged/chrome -n {name}-{version}-chrome.zip -o true",
"package": "npm run bump-version && npm run dist && npm run package:chrome && npm run package:firefox"
},
"private": true,
Expand Down Expand Up @@ -49,6 +49,6 @@
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.4.3",
"web-ext": "^7.11.0"
"web-ext": "^8.2.0"
}
}
}
16 changes: 16 additions & 0 deletions src/app/Directives/auto-focus.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { AfterContentInit, Directive, ElementRef, Input } from '@angular/core';

@Directive({
selector: '[appAutoFocus]',
standalone: true
})
export class AutoFocusDirective implements AfterContentInit {
@Input() public autoFocus: boolean | undefined;
constructor(private el: ElementRef) { }

public ngAfterContentInit(): void {
setTimeout(() => {
this.el.nativeElement.focus();
}, 100);
}
}
2 changes: 1 addition & 1 deletion src/app/Interceptors/token-interceptor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class TokenInterceptorService implements HttpInterceptor {
if (err.status === 401 || err.status === 403) {
this.notifier.error("Invalid Personal Access Token", 3000);
this.api.invalid_token = true;
this.router.navigate(['/settings'], { state: { data: {disable_back: true} } });
this.router.navigate(['/settings/account'], { state: { data: {disable_back: true} } });
}
if (err.status === 404) {
this.notifier.warning("Account missing");
Expand Down
3 changes: 2 additions & 1 deletion src/app/Models/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ export enum SwMessageType {
'CHECK_LOCKED' = 'CHECK-LOCKED',
'ENCRYPT_PAT' = 'ENCRYPT-PAT',
'RESET_EXT' = 'RESET-EXT',
'CHANGE_ENC_KEY' = 'CHANGE-ENC-KEY'
'CHANGE_ENC_KEY' = 'CHANGE-ENC-KEY',
'SET_DEBUG' = 'SET-DEBUG'
}
61 changes: 44 additions & 17 deletions src/app/Services/api/api.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Injectable} from '@angular/core';
import {HttpClient, HttpErrorResponse, HttpHeaders, HttpResponse} from '@angular/common/http';
import {HttpClient, HttpErrorResponse, HttpResponse} from '@angular/common/http';
import {Account} from "../../Models/account";
import {Otp} from "../../Models/otp";
import {IPref, Preferences} from "../../Models/preferences";
Expand All @@ -22,15 +22,20 @@ export class ApiService {
this._invalid_token = value;
}

/**
* Get a list of Accounts from the 2FAuth server
*/
public getAccounts(): Observable<Account[]> {
// Invalid token flag is set, return a blank list
if (this._invalid_token) {
return of([]);
}
return this.http.get<Account[]>(this.getUrl() + 'twofaccounts').pipe(
// Request the accounts from the server
return this.http.get<Account[]>(this.getAPIUrl('twofaccounts')).pipe(
switchMap(accounts => {
let blobStateObservables = accounts.map(account => {
if (account.icon !== null) {
return from(fetch(this.settings.get('host_url') + '/storage/icons/' + account.icon, {mode: 'no-cors'}).then((response: Response) => {
return from(fetch(this.getHostUrl(`storage/icons/${account.icon}`), {mode: 'no-cors'}).then((response: Response) => {
return response.blob();
})).pipe(
map((blob: Blob) => {
Expand All @@ -39,7 +44,7 @@ export class ApiService {
account.icon_src = blob;
} else {
// Otherwise, store the icons url
account.icon_src = this.settings.get('host_url') + '/storage/icons/' + account.icon;
account.icon_src = this.getHostUrl(`storage/icons/${account.icon}`);
}
return account;
})
Expand Down Expand Up @@ -68,6 +73,12 @@ export class ApiService {
)
}

/**
* Convert a Blob to a base64 string
*
* @param blob
* @private
*/
private blobToBase64(blob: Blob): Observable<string> {
const reader = new FileReader();
reader.readAsDataURL(blob);
Expand All @@ -79,19 +90,16 @@ export class ApiService {
});
}

/**
* Get the current OTP from the server
*
* @param account_id
*/
public getOtp(account_id: any): Observable<Otp> {
if (this._invalid_token) {
return of({} as Otp);
}
return this.http.get<Otp>(`${this.getUrl()}twofaccounts/${account_id}/otp`);
}

groups() {
// TODO
}

icons() {
// TODO
return this.http.get<Otp>(this.getAPIUrl(`twofaccounts/${account_id}/otp`));
}

/**
Expand All @@ -102,7 +110,7 @@ export class ApiService {
if (this._invalid_token) {
resolve(false);
}
let url = `${this.getUrl()}user/preferences`;
let url = this.getAPIUrl('user/preferences');
this.http.get<HttpResponse<any>>(url, {observe: 'response'}).subscribe({
next: response => {
if (response.status >= 200 && response.status < 400) {
Expand All @@ -118,11 +126,14 @@ export class ApiService {
})
}

/**
* Retrieve the users preferences from the 2FAuth server
*/
public getPreferences(): Observable<Preferences> {
if (this._invalid_token) {
return of({} as Preferences);
}
let url = `${this.getUrl()}user/preferences`;
let url = this.getAPIUrl('user/preferences');
return this.http.get<IPref[]>(url).pipe(
map((preferences: IPref[]) => {
let _map = <any>{};
Expand All @@ -134,7 +145,23 @@ export class ApiService {
);
}

private getUrl(): string {
return this.settings.get('host_url') + '/api/v1/';
/**
* Get a URL for the 2FAuth server.
*
* @param relative_url
* @private
*/
private getHostUrl(relative_url?: string): string {
return `${this.settings.get('host_url')}/${typeof relative_url !== 'undefined' ? relative_url : ''}`;
}

/**
* Get an API URL for the 2FAuth server.
*
* @param relative_url
* @private
*/
private getAPIUrl(relative_url?: string): string {
return this.getHostUrl(`api/v1/${typeof relative_url !== 'undefined' ? relative_url : ''}`);
}
}
4 changes: 2 additions & 2 deletions src/app/Services/initializer/initializer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export class InitializerService {
this.settings.set('decoded_pat', response.data.pat);
if (!this.settings.get("host_url") || !this.settings.get("host_pat")) {
// Missing the host URL or PAT, display the settings page so that they can be entered
this.router.navigate(['/settings'], {state: {data: {disable_back: true}}});
this.router.navigate(['/settings/account'], {state: {data: {disable_back: true}}});
} else if (this.api.invalid_token) {
this.notifier.error("Invalid Personal Access Token", 3000);
this.router.navigate(['/settings'], {state: {data: {disable_back: true}}});
this.router.navigate(['/settings/account'], {state: {data: {disable_back: true}}});
} else {
// Load the current user preferences from the server
this.preferences.updateFromServer();
Expand Down
2 changes: 1 addition & 1 deletion src/app/Services/preferences/preferences.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {StorageService, StorageType} from "../storage/storage.service";
})
export class PreferencesService extends StorageService {
constructor(zone: NgZone, @Optional() _preferences: PreferencesClass, private api: ApiService) {
let defaults = (_preferences)? _preferences : new PreferencesClass();
let defaults = (_preferences) || new PreferencesClass();
super(zone, defaults);
this.setStorageType(StorageType.local);
}
Expand Down
24 changes: 15 additions & 9 deletions src/app/Services/serviceworker/serviceworker.service.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { Injectable } from '@angular/core';
import {from, Observable, of, Subject} from "rxjs";
import {Notification} from "../../Models/notifications";
import {Injectable} from '@angular/core';
import {SwMessage, SwMessageType} from "../../Models/message";
import {runtime} from "webextension-polyfill";

@Injectable({
providedIn: 'root'
})
export class ServiceWorkerService {
constructor() {}
constructor() {
// @ts-ignore
window['setDebug'] = (enable_debug: boolean) => {
this.sendMessage(SwMessageType.SET_DEBUG, enable_debug ? 'ON' : 'OFF')
};

sendMessage(type: SwMessageType, payload: any = null): Promise<SwMessage> {
// @ts-ignore
window['resetExtension'] = () => {
this.sendMessage(SwMessageType.RESET_EXT);
};
}

async sendMessage(type: SwMessageType, payload: any = null): Promise<SwMessage> {
let message = new SwMessage();
message.name = type;
try {
return runtime.sendMessage({ type: type, payload: payload }).then(data => {
message.data = data;
return Promise.resolve(message);
});
message.data = await runtime.sendMessage({type: type, payload: payload});
return message;
} catch (error) {
return Promise.resolve(message);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/Services/settings/settings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {StorageService, StorageType} from "../storage/storage.service";
export class SettingsService extends StorageService {

constructor(zone: NgZone, @Optional() _settings: SettingsClass) {
let defaults = (_settings)? _settings : new SettingsClass();
let defaults = (_settings) || new SettingsClass();
super(zone, defaults);
this.setStorageType(StorageType.local);
}
Expand Down
64 changes: 28 additions & 36 deletions src/app/Services/storage/storage.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,14 @@ export class StorageService {
() => resolve(true),
() => resolve(false)
);
} else if (this.storeType !== StorageType.sessionStorage) {
// Put the object into localStorage
localStorage.setItem(this.storeKey, JSON.stringify(data));
resolve(true);
} else {
if (this.storeType !== StorageType.sessionStorage) {
// Put the object into localStorage
localStorage.setItem(this.storeKey, JSON.stringify(data));
resolve(true);
} else {
// Put the object into sessionStorage
sessionStorage.setItem(this.storeKey, JSON.stringify(data));
resolve(true);
}
// Put the object into sessionStorage
sessionStorage.setItem(this.storeKey, JSON.stringify(data));
resolve(true);
}
});
}
Expand All @@ -75,25 +73,23 @@ export class StorageService {
console.error(error);
reject();
});
} else if (this.storeType !== StorageType.sessionStorage) {
// Get from localStorage
let object = (localStorage.getItem(this.storeKey) === null) ? this.data : JSON.parse(localStorage.getItem(this.storeKey) || '[]');
resolve(object);
} else {
if (this.storeType !== StorageType.sessionStorage) {
// Get from localStorage
let object = (localStorage.getItem(this.storeKey) === null) ? this.data : JSON.parse(localStorage.getItem(this.storeKey) || '[]');
resolve(object);
} else {
// Get from sessionStorage
let object = (sessionStorage.getItem(this.storeKey) === null) ? this.data : JSON.parse(sessionStorage.getItem(this.storeKey) || '[]');
resolve(object);
}
// Get from sessionStorage
let object = (sessionStorage.getItem(this.storeKey) === null) ? this.data : JSON.parse(sessionStorage.getItem(this.storeKey) || '[]');
resolve(object);
}
});
}

/**
* Check if two objects are equal
*
* @param o1
* @param o2
* @param x
* @param y
* @protected
*/
protected deepEqual(x: any, y: any): boolean {
Expand All @@ -116,16 +112,14 @@ export class StorageService {
console.error(error);
resolve(false);
});
} else if (this.storeType !== StorageType.sessionStorage) {
// Clear localStorage
localStorage.clear();
resolve(true);
} else {
if (this.storeType !== StorageType.sessionStorage) {
// Clear localStorage
localStorage.clear();
resolve(true);
} else {
// Clear sessionStorage
sessionStorage.clear();
resolve(true);
}
// Clear sessionStorage
sessionStorage.clear();
resolve(true);
}
});
}
Expand All @@ -142,14 +136,12 @@ export class StorageService {
console.error(error);
resolve(false);
});
} else if (this.storeType !== StorageType.sessionStorage) {
localStorage.removeItem(key);
resolve(true);
} else {
if (this.storeType !== StorageType.sessionStorage) {
localStorage.removeItem(key);
resolve(true);
} else {
sessionStorage.removeItem(key);
resolve(true);
}
sessionStorage.removeItem(key);
resolve(true);
}
});
}
Expand Down
Loading

0 comments on commit f794fa3

Please sign in to comment.