"tslib": "^1.9.0"
}
},
+ "@auth0/angular-jwt": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-2.0.0.tgz",
+ "integrity": "sha512-RVlXFpcqQ+9uCpzboU7Tm1ubaRVO2FrR5+RYuwHtTT4BXquVMEwOSbAuuaArFud/kMc00XYoGgiP1JkCfOAfpA==",
+ "requires": {
+ "url": "^0.11.0"
+ }
+ },
"@babel/code-frame": {
"version": "7.0.0-beta.56",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.56.tgz",
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
- "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
- "dev": true
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
},
"querystring-es3": {
"version": "0.2.1",
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
"integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
- "dev": true,
"requires": {
"punycode": "1.3.2",
"querystring": "0.2.0"
"punycode": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
- "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
- "dev": true
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
}
}
},
"fix:prettier": "prettier --write \"{src,e2e}/**/*.{ts,scss}\"",
"fix:tslint": "npm run lint:tslint -- --fix",
"fix": "npm run fix:tslint; npm run fix:prettier"
-
},
"private": true,
"jest": {
"@angular/platform-browser": "6.1.4",
"@angular/platform-browser-dynamic": "6.1.4",
"@angular/router": "6.1.4",
+ "@auth0/angular-jwt": "^2.0.0",
"@swimlane/ngx-datatable": "13.1.0",
"@types/lodash": "4.14.116",
"awesome-bootstrap-checkbox": "0.3.7",
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { JwtModule } from '@auth0/angular-jwt';
import { ToastModule, ToastOptions } from 'ng2-toastr/ng2-toastr';
import { AccordionModule } from 'ngx-bootstrap/accordion';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
enableHTML = true;
}
+export function jwtTokenGetter() {
+ return localStorage.getItem('access_token');
+}
+
@NgModule({
declarations: [AppComponent],
imports: [
CephModule,
AccordionModule.forRoot(),
BsDropdownModule.forRoot(),
- TabsModule.forRoot()
+ TabsModule.forRoot(),
+ JwtModule.forRoot({
+ config: {
+ tokenGetter: jwtTokenGetter
+ }
+ })
],
exports: [SharedModule],
providers: [
</div>
</div>
- <!-- Stay signed in -->
- <div class="checkbox checkbox-primary">
- <input id="stay_signed_in"
- name="stay_signed_in"
- type="checkbox"
- [(ngModel)]="model.stay_signed_in">
- <label for="stay_signed_in"
- i18n="A checkbox on the login page to do not expire session on browser close">
- Keep me logged in
- </label>
- </div>
-
<input type="submit"
class="btn btn-primary btn-block"
[disabled]="loginForm.invalid"
+<form #docsForm action="/docs" target="_blank" method="post">
+ <input type="hidden" name="token"/>
+</form>
+
<div dropdown>
<a dropdownToggle
class="dropdown-toggle"
<li>
<a i18n
class="dropdown-item"
- href="/docs"
- target="_blank">API
+ (click)="goToApiDocs()">API
</a>
</li>
<li>
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe';
+import { AuthStorageService } from '../../../shared/services/auth-storage.service';
import { SummaryService } from '../../../shared/services/summary.service';
import { AboutComponent } from '../about/about.component';
styleUrls: ['./dashboard-help.component.scss']
})
export class DashboardHelpComponent implements OnInit {
+ @ViewChild('docsForm')
+ docsFormElement;
docsUrl: string;
modalRef: BsModalRef;
constructor(
private summaryService: SummaryService,
private cephReleaseNamePipe: CephReleaseNamePipe,
- private modalService: BsModalService
+ private modalService: BsModalService,
+ private authStorageService: AuthStorageService
) {}
ngOnInit() {
openAboutModal() {
this.modalRef = this.modalService.show(AboutComponent);
}
+
+ goToApiDocs() {
+ const tokenInput = this.docsFormElement.nativeElement.children[0];
+ tokenInput.value = this.authStorageService.getToken();
+ this.docsFormElement.nativeElement.submit();
+ }
}
'should login and save the user',
fakeAsync(() => {
const fakeCredentials = { username: 'foo', password: 'bar' };
+ const fakeResponse = { username: 'foo', token: 'tokenbytes' };
service.login(<any>fakeCredentials);
const req = httpTesting.expectOne('api/auth');
expect(req.request.method).toBe('POST');
expect(req.request.body).toEqual(fakeCredentials);
- req.flush(fakeCredentials);
+ req.flush(fakeResponse);
tick();
expect(localStorage.getItem('dashboard_username')).toBe('foo');
+ expect(localStorage.getItem('access_token')).toBe('tokenbytes');
})
);
import { Injectable } from '@angular/core';
import { Credentials } from '../models/credentials';
+import { LoginResponse } from '../models/login-response';
import { AuthStorageService } from '../services/auth-storage.service';
import { ApiModule } from './api.module';
return this.http
.post('api/auth', credentials)
.toPromise()
- .then((resp: Credentials) => {
- this.authStorageService.set(resp.username, resp.permissions);
+ .then((resp: LoginResponse) => {
+ this.authStorageService.set(resp.username, resp.token, resp.permissions);
});
}
export class Credentials {
username: string;
password: string;
- permissions: any;
- stay_signed_in = false;
}
--- /dev/null
+export class LoginResponse {
+ username: string;
+ token: string;
+ permissions: object;
+}
export class AuthStorageService {
constructor() {}
- set(username: string, permissions: any = {}) {
+ set(username: string, token: string, permissions: object = {}) {
localStorage.setItem('dashboard_username', username);
+ localStorage.setItem('access_token', token);
localStorage.setItem('dashboard_permissions', JSON.stringify(new Permissions(permissions)));
}
remove() {
+ localStorage.removeItem('access_token');
localStorage.removeItem('dashboard_username');
}
+ getToken(): string {
+ return localStorage.getItem('access_token');
+ }
+
isLoggedIn() {
return localStorage.getItem('dashboard_username') !== null;
}