1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 00:03:56 +00:00

stub out angular with webpack

This commit is contained in:
Kyle Spearrin
2018-04-03 22:14:54 -04:00
parent 848117ff86
commit 4d56d12ccb
19 changed files with 1225 additions and 38 deletions

View File

@@ -78,6 +78,7 @@
"webRequest",
"webRequestBlocking"
],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"commands": {
"autofill_login": {
"suggested_key": {

View File

@@ -0,0 +1,3 @@
<form id="login-page" #form>
Login Form
</form>

View File

@@ -0,0 +1,44 @@
import * as template from './login.component.html';
import {
Component,
ComponentFactoryResolver,
ViewChild,
ViewContainerRef,
} from '@angular/core';
import { Router } from '@angular/router';
import { ToasterService } from 'angular2-toaster';
import { Angulartics2 } from 'angulartics2';
import { AuthResult } from 'jslib/models/domain/authResult';
import { AuthService } from 'jslib/abstractions/auth.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { SyncService } from 'jslib/abstractions/sync.service';
@Component({
selector: 'app-login',
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) { }
async submit() {
}
togglePassword() {
this.analytics.eventTrack.next({ action: 'Toggled Master Password on Login' });
this.showPassword = !this.showPassword;
document.getElementById('masterPassword').focus();
}
}

View File

@@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import {
RouterModule,
Routes,
} from '@angular/router';
import { LoginComponent } from './accounts/login.component';
const routes: Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes, {
useHash: true,
/*enableTracing: true,*/
})],
exports: [RouterModule],
})
export class AppRoutingModule { }

View File

@@ -0,0 +1,39 @@
import {
ToasterConfig,
ToasterContainerComponent,
} from 'angular2-toaster';
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
import {
Component,
ComponentFactoryResolver,
NgZone,
OnDestroy,
OnInit,
Type,
ViewChild,
ViewContainerRef,
} from '@angular/core';
import { Router } from '@angular/router';
import { ToasterService } from 'angular2-toaster';
import { Angulartics2 } from 'angulartics2';
@Component({
selector: 'app-root',
styles: [],
template: `
<toaster-container [toasterconfig]="toasterConfig"></toaster-container>
<router-outlet></router-outlet>`,
})
export class AppComponent {
toasterConfig: ToasterConfig = new ToasterConfig({
showCloseButton: true,
mouseoverTimerStop: true,
animation: 'flyRight',
limit: 5,
});
constructor(private angulartics2GoogleAnalytics: Angulartics2GoogleAnalytics, private analytics: Angulartics2,
private toasterService: ToasterService) { }
}

1
src/popup2/app.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
declare module '*.html';

44
src/popup2/app.module.ts Normal file
View File

@@ -0,0 +1,44 @@
import 'core-js';
import 'zone.js/dist/zone';
import { ToasterModule } from 'angular2-toaster';
import { Angulartics2Module } from 'angulartics2';
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
import { AppRoutingModule } from './app-routing.module';
import { ServicesModule } from './services/services.module';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { LoginComponent } from './accounts/login.component';
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
AppRoutingModule,
ServicesModule,
Angulartics2Module.forRoot([Angulartics2GoogleAnalytics], {
pageTracking: {
clearQueryParams: true,
},
}),
ToasterModule,
],
declarations: [
AppComponent,
LoginComponent,
],
entryComponents: [
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule { }

14
src/popup2/index.html Normal file
View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bitwarden</title>
<base href="">
</head>
<body>
<app-root>
<div id="loading"><i class="fa fa-spinner fa-spin fa-3x"></i></div>
</app-root>
</body>
</html>

15
src/popup2/main.ts Normal file
View File

@@ -0,0 +1,15 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
// tslint:disable-next-line
require('../scss/popup.scss');
// tslint:disable-next-line
require('../scripts/duo.js');
import { AppModule } from './app.module';
//if (!isDev()) {
// enableProdMode();
//}
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@@ -0,0 +1,31 @@
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;
}
}

View File

@@ -0,0 +1,33 @@
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);
}
}
}

View File

@@ -0,0 +1,35 @@
import {
APP_INITIALIZER,
NgModule,
} from '@angular/core';
import { ToasterModule } from 'angular2-toaster';
import { AuthGuardService } from './auth-guard.service';
import { BroadcasterService } from './broadcaster.service';
import { ValidationService } from './validation.service';
function initFactory(): Function {
return async () => {
};
}
@NgModule({
imports: [
ToasterModule,
],
declarations: [],
providers: [
ValidationService,
AuthGuardService,
{
provide: APP_INITIALIZER,
useFactory: initFactory,
deps: [],
multi: true,
},
],
})
export class ServicesModule {
}

View File

@@ -0,0 +1,37 @@
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;
}
}

3
src/scss/popup.scss Normal file
View File

@@ -0,0 +1,3 @@
body {
color: black;
}