mirror of
https://github.com/bitwarden/browser.git
synced 2025-03-22 15:19:15 +01:00
load service module
This commit is contained in:
parent
4d56d12ccb
commit
5fd400bf9d
2
jslib
2
jslib
@ -1 +1 @@
|
||||
Subproject commit 167558168c4ddff8eff67d7f12dfac47d5d25866
|
||||
Subproject commit 579f970323ea0bbc0d26f17cb9454c142f47bf6a
|
@ -1,3 +1,43 @@
|
||||
<form id="login-page" #form>
|
||||
Login Form
|
||||
<form id="login-page" #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<div class="content">
|
||||
<p class="lead">{{'loginOrCreateNewAccount' | i18n}}</p>
|
||||
<div class="box last">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="email">{{'emailAddress' | i18n}}</label>
|
||||
<input id="email" type="text" name="Email" [(ngModel)]="email" required
|
||||
[appAutofocus]="email === ''">
|
||||
</div>
|
||||
<div class="box-content-row box-content-row-flex" appBoxRow>
|
||||
<div class="row-main">
|
||||
<label for="masterPassword">{{'masterPass' | i18n}}</label>
|
||||
<input id="masterPassword" type="{{showPassword ? 'text' : 'password'}}" name="MasterPassword"
|
||||
class="monospaced" [(ngModel)]="masterPassword" required [appAutofocus]="email !== ''">
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<a class="row-btn" href="#" appStopClick appBlurClick
|
||||
title="{{'toggleVisibility' | i18n}}" (click)="togglePassword()">
|
||||
<i class="fa fa-lg"
|
||||
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<button type="submit" class="btn primary block" [disabled]="form.loading" appBlurClick>
|
||||
<span [hidden]="form.loading"><i class="fa fa-sign-in"></i> {{'logIn' | i18n}}</span>
|
||||
<i class="fa fa-spinner fa-spin" [hidden]="!form.loading"></i>
|
||||
</button>
|
||||
<a routerLink="/register" class="btn block">
|
||||
<i class="fa fa-pencil-square-o"></i> {{'createAccount' | i18n}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="sub-options">
|
||||
<a routerLink="/hint">{{'getMasterPasswordHint' | i18n}}</a>
|
||||
</div>
|
||||
<a href="#" appStopClick (click)="settings()" class="settings-icon">
|
||||
<i class="fa fa-cog fa-lg"></i><span> {{'settings' | i18n}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -22,18 +22,44 @@ import { SyncService } from 'jslib/abstractions/sync.service';
|
||||
template: template,
|
||||
})
|
||||
export class LoginComponent {
|
||||
@ViewChild('environment', { read: ViewContainerRef }) environmentModal: ViewContainerRef;
|
||||
|
||||
email: string = '';
|
||||
masterPassword: string = '';
|
||||
showPassword: boolean = false;
|
||||
formPromise: Promise<AuthResult>;
|
||||
|
||||
constructor(private router: Router, private analytics: Angulartics2,
|
||||
private toasterService: ToasterService) { }
|
||||
constructor(private authService: AuthService, private router: Router,
|
||||
private analytics: Angulartics2, private toasterService: ToasterService,
|
||||
private i18nService: I18nService, private syncService: SyncService) { }
|
||||
|
||||
async submit() {
|
||||
|
||||
if (this.email == null || this.email === '') {
|
||||
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),
|
||||
this.i18nService.t('emailRequired'));
|
||||
return;
|
||||
}
|
||||
if (this.email.indexOf('@') === -1) {
|
||||
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),
|
||||
this.i18nService.t('invalidEmail'));
|
||||
return;
|
||||
}
|
||||
if (this.masterPassword == null || this.masterPassword === '') {
|
||||
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),
|
||||
this.i18nService.t('masterPassRequired'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.formPromise = this.authService.logIn(this.email, this.masterPassword);
|
||||
const response = await this.formPromise;
|
||||
if (response.twoFactor) {
|
||||
this.analytics.eventTrack.next({ action: 'Logged In To Two-step' });
|
||||
this.router.navigate(['2fa']);
|
||||
} else {
|
||||
this.syncService.fullSync(true);
|
||||
this.analytics.eventTrack.next({ action: 'Logged In' });
|
||||
this.router.navigate(['vault']);
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
togglePassword() {
|
||||
|
@ -17,6 +17,15 @@ import { AppComponent } from './app.component';
|
||||
|
||||
import { LoginComponent } from './accounts/login.component';
|
||||
|
||||
import { ApiActionDirective } from 'jslib/angular/directives/api-action.directive';
|
||||
import { AutofocusDirective } from 'jslib/angular/directives/autofocus.directive';
|
||||
import { BlurClickDirective } from 'jslib/angular/directives/blur-click.directive';
|
||||
import { FallbackSrcDirective } from 'jslib/angular/directives/fallback-src.directive';
|
||||
import { StopClickDirective } from 'jslib/angular/directives/stop-click.directive';
|
||||
import { StopPropDirective } from 'jslib/angular/directives/stop-prop.directive';
|
||||
|
||||
import { I18nPipe } from 'jslib/angular/pipes/i18n.pipe';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -32,8 +41,15 @@ import { LoginComponent } from './accounts/login.component';
|
||||
ToasterModule,
|
||||
],
|
||||
declarations: [
|
||||
ApiActionDirective,
|
||||
AppComponent,
|
||||
AutofocusDirective,
|
||||
BlurClickDirective,
|
||||
FallbackSrcDirective,
|
||||
I18nPipe,
|
||||
LoginComponent,
|
||||
StopClickDirective,
|
||||
StopPropDirective
|
||||
],
|
||||
entryComponents: [
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
CanActivate,
|
||||
Router,
|
||||
} from '@angular/router';
|
||||
|
||||
import { CryptoService } from 'jslib/abstractions/crypto.service';
|
||||
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||
import { UserService } from 'jslib/abstractions/user.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuthGuardService implements CanActivate {
|
||||
constructor(private cryptoService: CryptoService, private userService: UserService, private router: Router,
|
||||
private messagingService: MessagingService) { }
|
||||
|
||||
async canActivate() {
|
||||
const isAuthed = await this.userService.isAuthenticated();
|
||||
if (!isAuthed) {
|
||||
this.messagingService.send('logout');
|
||||
return false;
|
||||
}
|
||||
|
||||
const key = await this.cryptoService.getKey();
|
||||
if (key == null) {
|
||||
this.router.navigate(['lock']);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class BroadcasterService {
|
||||
subscribers: Map<string, (message: any) => any> = new Map<string, (message: any) => any>();
|
||||
|
||||
send(message: any, id?: string) {
|
||||
if (id != null) {
|
||||
if (this.subscribers.has(id)) {
|
||||
this.subscribers.get(id)(message);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.subscribers.forEach((value) => {
|
||||
value(message);
|
||||
});
|
||||
}
|
||||
|
||||
subscribe(id: string, messageCallback: (message: any) => any) {
|
||||
if (this.subscribers.has(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.subscribers.set(id, messageCallback);
|
||||
}
|
||||
|
||||
unsubscribe(id: string) {
|
||||
if (this.subscribers.has(id)) {
|
||||
this.subscribers.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,13 +5,59 @@ import {
|
||||
|
||||
import { ToasterModule } from 'angular2-toaster';
|
||||
|
||||
import { AuthGuardService } from './auth-guard.service';
|
||||
import { BroadcasterService } from './broadcaster.service';
|
||||
import { ValidationService } from './validation.service';
|
||||
import { AuthGuardService } from 'jslib/angular/services/auth-guard.service';
|
||||
import { ValidationService } from 'jslib/angular/services/validation.service';
|
||||
|
||||
import { BrowserApi } from '../../browser/browserApi';
|
||||
|
||||
import { ApiService } from 'jslib/abstractions/api.service';
|
||||
import { AppIdService } from 'jslib/abstractions/appId.service';
|
||||
import { AuthService as AuthServiceAbstraction } from 'jslib/abstractions/auth.service';
|
||||
import { AuditService } from 'jslib/abstractions/audit.service';
|
||||
import { CipherService } from 'jslib/abstractions/cipher.service';
|
||||
import { CollectionService } from 'jslib/abstractions/collection.service';
|
||||
import { CryptoService } from 'jslib/abstractions/crypto.service';
|
||||
import { EnvironmentService } from 'jslib/abstractions/environment.service';
|
||||
import { FolderService } from 'jslib/abstractions/folder.service';
|
||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||
import { LockService } from 'jslib/abstractions/lock.service';
|
||||
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||
import { PasswordGenerationService } from 'jslib/abstractions/passwordGeneration.service';
|
||||
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
||||
import { SettingsService } from 'jslib/abstractions/settings.service';
|
||||
import { StorageService } from 'jslib/abstractions/storage.service';
|
||||
import { SyncService } from 'jslib/abstractions/sync.service';
|
||||
import { TokenService } from 'jslib/abstractions/token.service';
|
||||
import { TotpService } from 'jslib/abstractions/totp.service';
|
||||
import { UserService } from 'jslib/abstractions/user.service';
|
||||
import { UtilsService } from 'jslib/abstractions/utils.service';
|
||||
|
||||
import { AutofillService } from '../../services/abstractions/autofill.service';
|
||||
|
||||
import BrowserMessagingService from '../../services/browserMessaging.service';
|
||||
|
||||
import { AuthService } from 'jslib/services/auth.service';
|
||||
import { ConstantsService } from 'jslib/services/constants.service';
|
||||
|
||||
function getBgService<T>(service: string) {
|
||||
return (): T => {
|
||||
const page = BrowserApi.getBackgroundPage();
|
||||
return page ? page.bitwardenMain[service] as T : null;
|
||||
};
|
||||
}
|
||||
|
||||
const messagingService = new BrowserMessagingService(getBgService<PlatformUtilsService>('platformUtilsService')());
|
||||
const authService = new AuthService(getBgService<CryptoService>('cryptoService')(),
|
||||
getBgService<ApiService>('apiService')(), getBgService<UserService>('userService')(),
|
||||
getBgService<TokenService>('tokenService')(), getBgService<AppIdService>('appIdService')(),
|
||||
getBgService<I18nService>('i18n2Service')(), getBgService<PlatformUtilsService>('platformUtilsService')(),
|
||||
getBgService<ConstantsService>('constantsService')(), messagingService);
|
||||
|
||||
function initFactory(): Function {
|
||||
return async () => {
|
||||
|
||||
if (getBgService<I18nService>('i18n2Service')() != null) {
|
||||
authService.init();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -23,6 +69,36 @@ function initFactory(): Function {
|
||||
providers: [
|
||||
ValidationService,
|
||||
AuthGuardService,
|
||||
{ provide: MessagingService, useValue: messagingService },
|
||||
{ provide: AuthServiceAbstraction, useValue: authService },
|
||||
{ provide: AuditService, useFactory: getBgService<AuditService>('auditService'), deps: [] },
|
||||
{ provide: CipherService, useFactory: getBgService<CipherService>('cipherService'), deps: [] },
|
||||
{ provide: FolderService, useFactory: getBgService<FolderService>('folderService'), deps: [] },
|
||||
{ provide: CollectionService, useFactory: getBgService<CollectionService>('collectionService'), deps: [] },
|
||||
{ provide: EnvironmentService, useFactory: getBgService<EnvironmentService>('environmentService'), deps: [] },
|
||||
{ provide: TotpService, useFactory: getBgService<TotpService>('totpService'), deps: [] },
|
||||
{ provide: TokenService, useFactory: getBgService<TokenService>('tokenService'), deps: [] },
|
||||
{ provide: I18nService, useFactory: getBgService<I18nService>('i18n2Service'), deps: [] },
|
||||
{ provide: UtilsService, useFactory: getBgService<UtilsService>('utilsService'), deps: [] },
|
||||
{ provide: CryptoService, useFactory: getBgService<CryptoService>('cryptoService'), deps: [] },
|
||||
{
|
||||
provide: PlatformUtilsService,
|
||||
useFactory: getBgService<PlatformUtilsService>('platformUtilsService'),
|
||||
deps: []
|
||||
},
|
||||
{
|
||||
provide: PasswordGenerationService,
|
||||
useFactory: getBgService<PasswordGenerationService>('passwordGenerationService'),
|
||||
deps: []
|
||||
},
|
||||
{ provide: ApiService, useFactory: getBgService<ApiService>('apiService'), deps: [] },
|
||||
{ provide: SyncService, useFactory: getBgService<SyncService>('syncService'), deps: [] },
|
||||
{ provide: UserService, useFactory: getBgService<UserService>('userService'), deps: [] },
|
||||
{ provide: SettingsService, useFactory: getBgService<SettingsService>('settingsService'), deps: [] },
|
||||
{ provide: LockService, useFactory: getBgService<LockService>('lockService'), deps: [] },
|
||||
{ provide: StorageService, useFactory: getBgService<StorageService>('storageService'), deps: [] },
|
||||
{ provide: AppIdService, useFactory: getBgService<AppIdService>('appIdService'), deps: [] },
|
||||
{ provide: AutofillService, useFactory: getBgService<AutofillService>('autofillService'), deps: [] },
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: initFactory,
|
||||
|
@ -1,37 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { ToasterService } from 'angular2-toaster';
|
||||
|
||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||
|
||||
@Injectable()
|
||||
export class ValidationService {
|
||||
constructor(private toasterService: ToasterService, private i18nService: I18nService) { }
|
||||
|
||||
showError(data: any): string[] {
|
||||
const defaultErrorMessage = this.i18nService.t('unexpectedError');
|
||||
const errors: string[] = [];
|
||||
|
||||
if (data == null || typeof data !== 'object') {
|
||||
errors.push(defaultErrorMessage);
|
||||
} else if (data.validationErrors == null) {
|
||||
errors.push(data.message ? data.message : defaultErrorMessage);
|
||||
} else {
|
||||
for (const key in data.validationErrors) {
|
||||
if (!data.validationErrors.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
data.validationErrors[key].forEach((item: string) => {
|
||||
errors.push(item);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), errors[0]);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import AutofillPageDetails from '../../models/autofillPageDetails';
|
||||
|
||||
export interface AutofillService {
|
||||
getFormsWithPasswordFields(pageDetails: AutofillPageDetails): any[];
|
||||
doAutoFill(options: any): Promise<string>;
|
||||
doAutoFillForLastUsedLogin(pageDetails: any, fromCommand: boolean): Promise<void>;
|
||||
export abstract class AutofillService {
|
||||
getFormsWithPasswordFields: (pageDetails: AutofillPageDetails) => any[];
|
||||
doAutoFill: (options: any) => Promise<string>;
|
||||
doAutoFillForLastUsedLogin: (pageDetails: any, fromCommand: boolean) => Promise<void>;
|
||||
}
|
||||
|
10
webpack2.js
10
webpack2.js
@ -135,13 +135,19 @@ module.exports = {
|
||||
{ from: './src/images', to: 'images' },
|
||||
{ from: './src/content/autofill.css', to: 'content' }
|
||||
]),
|
||||
new webpack.SourceMapDevToolPlugin({
|
||||
filename: '[name].js.map',
|
||||
include: ['popup/main.js']
|
||||
}),
|
||||
extractCss
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.js'],
|
||||
alias: {
|
||||
jslib: path.join(__dirname, 'jslib/src')
|
||||
}
|
||||
jslib: path.join(__dirname, 'jslib/src'),
|
||||
},
|
||||
symlinks: false,
|
||||
modules: [path.resolve('node_modules')]
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
|
Loading…
Reference in New Issue
Block a user