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:
@@ -78,6 +78,7 @@
|
||||
"webRequest",
|
||||
"webRequestBlocking"
|
||||
],
|
||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
"commands": {
|
||||
"autofill_login": {
|
||||
"suggested_key": {
|
||||
|
||||
3
src/popup2/accounts/login.component.html
Normal file
3
src/popup2/accounts/login.component.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<form id="login-page" #form>
|
||||
Login Form
|
||||
</form>
|
||||
44
src/popup2/accounts/login.component.ts
Normal file
44
src/popup2/accounts/login.component.ts
Normal 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();
|
||||
}
|
||||
}
|
||||
21
src/popup2/app-routing.module.ts
Normal file
21
src/popup2/app-routing.module.ts
Normal 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 { }
|
||||
39
src/popup2/app.component.ts
Normal file
39
src/popup2/app.component.ts
Normal 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
1
src/popup2/app.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module '*.html';
|
||||
44
src/popup2/app.module.ts
Normal file
44
src/popup2/app.module.ts
Normal 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
14
src/popup2/index.html
Normal 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
15
src/popup2/main.ts
Normal 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);
|
||||
31
src/popup2/services/auth-guard.service.ts
Normal file
31
src/popup2/services/auth-guard.service.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
33
src/popup2/services/broadcaster.service.ts
Normal file
33
src/popup2/services/broadcaster.service.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/popup2/services/services.module.ts
Normal file
35
src/popup2/services/services.module.ts
Normal 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 {
|
||||
}
|
||||
37
src/popup2/services/validation.service.ts
Normal file
37
src/popup2/services/validation.service.ts
Normal 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
3
src/scss/popup.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
color: black;
|
||||
}
|
||||
Reference in New Issue
Block a user