convert api, appid, and token services to jslib

This commit is contained in:
Kyle Spearrin 2018-01-09 16:20:15 -05:00
parent e1a513670f
commit 56bde82b41
11 changed files with 24 additions and 682 deletions

View File

@ -1,15 +1,21 @@
import { CipherType } from 'jslib/enums'; import { CipherType } from 'jslib/enums';
import { import {
ApiService,
AppIdService,
CryptoService, CryptoService,
TokenService,
UtilsService, UtilsService,
} from 'jslib/services'; } from 'jslib/services';
import { import {
ApiService as ApiServiceAbstraction,
AppIdService as AppIdServiceAbstraction,
CryptoService as CryptoServiceAbstraction, CryptoService as CryptoServiceAbstraction,
MessagingService as MessagingServiceAbstraction, MessagingService as MessagingServiceAbstraction,
PlatformUtilsService as PlatformUtilsServiceAbstraction, PlatformUtilsService as PlatformUtilsServiceAbstraction,
StorageService as StorageServiceAbstraction, StorageService as StorageServiceAbstraction,
TokenService as TokenServiceAbstraction,
UtilsService as UtilsServiceAbstraction, UtilsService as UtilsServiceAbstraction,
} from 'jslib/abstractions'; } from 'jslib/abstractions';
@ -23,8 +29,6 @@ import TabsBackground from './tabs.background';
import WebRequestBackground from './webRequest.background'; import WebRequestBackground from './webRequest.background';
import WindowsBackground from './windows.background'; import WindowsBackground from './windows.background';
import ApiService from '../services/api.service';
import AppIdService from '../services/appId.service';
import AutofillService from '../services/autofill.service'; import AutofillService from '../services/autofill.service';
import BrowserMessagingService from '../services/browserMessaging.service'; import BrowserMessagingService from '../services/browserMessaging.service';
import BrowserPlatformUtilsService from '../services/browserPlatformUtils.service'; import BrowserPlatformUtilsService from '../services/browserPlatformUtils.service';
@ -40,7 +44,6 @@ import LockService from '../services/lock.service';
import PasswordGenerationService from '../services/passwordGeneration.service'; import PasswordGenerationService from '../services/passwordGeneration.service';
import SettingsService from '../services/settings.service'; import SettingsService from '../services/settings.service';
import SyncService from '../services/sync.service'; import SyncService from '../services/sync.service';
import TokenService from '../services/token.service';
import TotpService from '../services/totp.service'; import TotpService from '../services/totp.service';
import UserService from '../services/user.service'; import UserService from '../services/user.service';
@ -52,9 +55,9 @@ export default class MainBackground {
utilsService: UtilsServiceAbstraction; utilsService: UtilsServiceAbstraction;
constantsService: ConstantsService; constantsService: ConstantsService;
cryptoService: CryptoServiceAbstraction; cryptoService: CryptoServiceAbstraction;
tokenService: TokenService; tokenService: TokenServiceAbstraction;
appIdService: AppIdService; appIdService: AppIdServiceAbstraction;
apiService: ApiService; apiService: ApiServiceAbstraction;
environmentService: EnvironmentService; environmentService: EnvironmentService;
userService: UserService; userService: UserService;
settingsService: SettingsService; settingsService: SettingsService;

View File

@ -1,6 +1,9 @@
import { ApiService } from 'jslib/abstractions/api.service';
import { AppIdService } from 'jslib/abstractions/appId.service';
import { CryptoService } from 'jslib/abstractions/crypto.service'; import { CryptoService } from 'jslib/abstractions/crypto.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service'; import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { StorageService } from 'jslib/abstractions/storage.service'; import { StorageService } from 'jslib/abstractions/storage.service';
import { TokenService } from 'jslib/abstractions/token.service';
import { UtilsService } from 'jslib/abstractions/utils.service'; import { UtilsService } from 'jslib/abstractions/utils.service';
function getBackgroundService<T>(service: string) { function getBackgroundService<T>(service: string) {
@ -11,10 +14,10 @@ function getBackgroundService<T>(service: string) {
} }
export const storageService = getBackgroundService<StorageService>('storageService'); export const storageService = getBackgroundService<StorageService>('storageService');
export const tokenService = getBackgroundService<any>('tokenService'); export const tokenService = getBackgroundService<TokenService>('tokenService');
export const cryptoService = getBackgroundService<any>('cryptoService'); export const cryptoService = getBackgroundService<any>('cryptoService');
export const userService = getBackgroundService<any>('userService'); export const userService = getBackgroundService<any>('userService');
export const apiService = getBackgroundService<any>('apiService'); export const apiService = getBackgroundService<ApiService>('apiService');
export const folderService = getBackgroundService<any>('folderService'); export const folderService = getBackgroundService<any>('folderService');
export const cipherService = getBackgroundService<CryptoService>('cipherService'); export const cipherService = getBackgroundService<CryptoService>('cipherService');
export const syncService = getBackgroundService<any>('syncService'); export const syncService = getBackgroundService<any>('syncService');
@ -22,7 +25,7 @@ export const autofillService = getBackgroundService<any>('autofillService');
export const passwordGenerationService = getBackgroundService<any>('passwordGenerationService'); export const passwordGenerationService = getBackgroundService<any>('passwordGenerationService');
export const platformUtilsService = getBackgroundService<PlatformUtilsService>('platformUtilsService'); export const platformUtilsService = getBackgroundService<PlatformUtilsService>('platformUtilsService');
export const utilsService = getBackgroundService<UtilsService>('utilsService'); export const utilsService = getBackgroundService<UtilsService>('utilsService');
export const appIdService = getBackgroundService<any>('appIdService'); export const appIdService = getBackgroundService<AppIdService>('appIdService');
export const i18nService = getBackgroundService<any>('i18nService'); export const i18nService = getBackgroundService<any>('i18nService');
export const constantsService = getBackgroundService<any>('constantsService'); export const constantsService = getBackgroundService<any>('constantsService');
export const settingsService = getBackgroundService<any>('settingsService'); export const settingsService = getBackgroundService<any>('settingsService');

View File

@ -1,461 +0,0 @@
import AppIdService from './appId.service';
import ConstantsService from './constants.service';
import TokenService from './token.service';
import { PlatformUtilsService } from 'jslib/abstractions';
import { EnvironmentUrls } from 'jslib/models/domain';
import {
CipherRequest,
DeviceRequest,
DeviceTokenRequest,
FolderRequest,
PasswordHintRequest,
RegisterRequest,
TokenRequest,
TwoFactorEmailRequest,
} from 'jslib/models/request';
import {
AttachmentResponse,
CipherResponse,
DeviceResponse,
DomainsResponse,
ErrorResponse,
FolderResponse,
GlobalDomainResponse,
IdentityTokenResponse,
KeysResponse,
ListResponse,
ProfileOrganizationResponse,
ProfileResponse,
SyncResponse,
} from 'jslib/models/response';
export default class ApiService {
urlsSet: boolean = false;
baseUrl: string;
identityBaseUrl: string;
deviceType: string;
logoutCallback: Function;
constructor(private tokenService: TokenService, platformUtilsService: PlatformUtilsService,
logoutCallback: Function) {
this.logoutCallback = logoutCallback;
this.deviceType = platformUtilsService.getDevice().toString();
}
setUrls(urls: EnvironmentUrls) {
this.urlsSet = true;
if (urls.base != null) {
this.baseUrl = urls.base + '/api';
this.identityBaseUrl = urls.base + '/identity';
return;
}
if (urls.api != null && urls.identity != null) {
this.baseUrl = urls.api;
this.identityBaseUrl = urls.identity;
return;
}
/* tslint:disable */
// Desktop
//this.baseUrl = 'http://localhost:4000';
//this.identityBaseUrl = 'http://localhost:33656';
// Desktop HTTPS
//this.baseUrl = 'https://localhost:44377';
//this.identityBaseUrl = 'https://localhost:44392';
// Desktop external
//this.baseUrl = 'http://192.168.1.3:4000';
//this.identityBaseUrl = 'http://192.168.1.3:33656';
// Preview
//this.baseUrl = 'https://preview-api.bitwarden.com';
//this.identityBaseUrl = 'https://preview-identity.bitwarden.com';
// Production
this.baseUrl = 'https://api.bitwarden.com';
this.identityBaseUrl = 'https://identity.bitwarden.com';
/* tslint:enable */
}
// Auth APIs
async postIdentityToken(request: TokenRequest): Promise<IdentityTokenResponse | any> {
const response = await fetch(new Request(this.identityBaseUrl + '/connect/token', {
body: this.qsStringify(request.toIdentityToken()),
cache: 'no-cache',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'Accept': 'application/json',
'Device-Type': this.deviceType,
}),
method: 'POST',
}));
let responseJson: any = null;
const typeHeader = response.headers.get('content-type');
if (typeHeader != null && typeHeader.indexOf('application/json') > -1) {
responseJson = await response.json();
}
if (responseJson != null) {
if (response.status === 200) {
return new IdentityTokenResponse(responseJson);
} else if (response.status === 400 && responseJson.TwoFactorProviders2 &&
Object.keys(responseJson.TwoFactorProviders2).length) {
await this.tokenService.clearTwoFactorToken(request.email);
return responseJson.TwoFactorProviders2;
}
}
return Promise.reject(new ErrorResponse(responseJson, response.status, true));
}
async refreshIdentityToken(): Promise<any> {
try {
await this.doRefreshToken();
} catch (e) {
return Promise.reject(null);
}
}
// Two Factor APIs
async postTwoFactorEmail(request: TwoFactorEmailRequest): Promise<any> {
const response = await fetch(new Request(this.baseUrl + '/two-factor/send-email-login', {
body: JSON.stringify(request),
cache: 'no-cache',
headers: new Headers({
'Content-Type': 'application/json; charset=utf-8',
'Device-Type': this.deviceType,
}),
method: 'POST',
}));
if (response.status !== 200) {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
// Account APIs
async getAccountRevisionDate(): Promise<number> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/accounts/revision-date', {
cache: 'no-cache',
headers: new Headers({
'Accept': 'application/json',
'Authorization': authHeader,
'Device-Type': this.deviceType,
}),
}));
if (response.status === 200) {
return (await response.json() as number);
} else {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
async postPasswordHint(request: PasswordHintRequest): Promise<any> {
const response = await fetch(new Request(this.baseUrl + '/accounts/password-hint', {
body: JSON.stringify(request),
cache: 'no-cache',
headers: new Headers({
'Content-Type': 'application/json; charset=utf-8',
'Device-Type': this.deviceType,
}),
method: 'POST',
}));
if (response.status !== 200) {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
async postRegister(request: RegisterRequest): Promise<any> {
const response = await fetch(new Request(this.baseUrl + '/accounts/register', {
body: JSON.stringify(request),
cache: 'no-cache',
headers: new Headers({
'Content-Type': 'application/json; charset=utf-8',
'Device-Type': this.deviceType,
}),
method: 'POST',
}));
if (response.status !== 200) {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
// Folder APIs
async postFolder(request: FolderRequest): Promise<FolderResponse> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/folders', {
body: JSON.stringify(request),
cache: 'no-cache',
headers: new Headers({
'Accept': 'application/json',
'Authorization': authHeader,
'Content-Type': 'application/json; charset=utf-8',
'Device-Type': this.deviceType,
}),
method: 'POST',
}));
if (response.status === 200) {
const responseJson = await response.json();
return new FolderResponse(responseJson);
} else {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
async putFolder(id: string, request: FolderRequest): Promise<FolderResponse> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/folders/' + id, {
body: JSON.stringify(request),
cache: 'no-cache',
headers: new Headers({
'Accept': 'application/json',
'Authorization': authHeader,
'Content-Type': 'application/json; charset=utf-8',
'Device-Type': this.deviceType,
}),
method: 'PUT',
}));
if (response.status === 200) {
const responseJson = await response.json();
return new FolderResponse(responseJson);
} else {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
async deleteFolder(id: string): Promise<any> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/folders/' + id, {
cache: 'no-cache',
headers: new Headers({
'Authorization': authHeader,
'Device-Type': this.deviceType,
}),
method: 'DELETE',
}));
if (response.status !== 200) {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
// Cipher APIs
async postCipher(request: CipherRequest): Promise<CipherResponse> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/ciphers', {
body: JSON.stringify(request),
cache: 'no-cache',
headers: new Headers({
'Accept': 'application/json',
'Authorization': authHeader,
'Content-Type': 'application/json; charset=utf-8',
'Device-Type': this.deviceType,
}),
method: 'POST',
}));
if (response.status === 200) {
const responseJson = await response.json();
return new CipherResponse(responseJson);
} else {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
async putCipher(id: string, request: CipherRequest): Promise<CipherResponse> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/ciphers/' + id, {
body: JSON.stringify(request),
cache: 'no-cache',
headers: new Headers({
'Accept': 'application/json',
'Authorization': authHeader,
'Content-Type': 'application/json; charset=utf-8',
'Device-Type': this.deviceType,
}),
method: 'PUT',
}));
if (response.status === 200) {
const responseJson = await response.json();
return new CipherResponse(responseJson);
} else {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
async deleteCipher(id: string): Promise<any> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/ciphers/' + id, {
cache: 'no-cache',
headers: new Headers({
'Authorization': authHeader,
'Device-Type': this.deviceType,
}),
method: 'DELETE',
}));
if (response.status !== 200) {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
// Attachments APIs
async postCipherAttachment(id: string, data: FormData): Promise<CipherResponse> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/ciphers/' + id + '/attachment', {
body: data,
cache: 'no-cache',
headers: new Headers({
'Accept': 'application/json',
'Authorization': authHeader,
'Device-Type': this.deviceType,
}),
method: 'POST',
}));
if (response.status === 200) {
const responseJson = await response.json();
return new CipherResponse(responseJson);
} else {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
async deleteCipherAttachment(id: string, attachmentId: string): Promise<any> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/ciphers/' + id + '/attachment/' + attachmentId, {
cache: 'no-cache',
headers: new Headers({
'Authorization': authHeader,
'Device-Type': this.deviceType,
}),
method: 'DELETE',
}));
if (response.status !== 200) {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
// Sync APIs
async getSync(): Promise<SyncResponse> {
const authHeader = await this.handleTokenState();
const response = await fetch(new Request(this.baseUrl + '/sync', {
cache: 'no-cache',
headers: new Headers({
'Accept': 'application/json',
'Authorization': authHeader,
'Device-Type': this.deviceType,
}),
}));
if (response.status === 200) {
const responseJson = await response.json();
return new SyncResponse(responseJson);
} else {
const error = await this.handleError(response, false);
return Promise.reject(error);
}
}
// Helpers
private async handleError(response: Response, tokenError: boolean): Promise<ErrorResponse> {
if ((tokenError && response.status === 400) || response.status === 401 || response.status === 403) {
this.logoutCallback(true);
return null;
}
let responseJson: any = null;
const typeHeader = response.headers.get('content-type');
if (typeHeader != null && typeHeader.indexOf('application/json') > -1) {
responseJson = await response.json();
}
return new ErrorResponse(responseJson, response.status, tokenError);
}
private async handleTokenState(): Promise<string> {
let accessToken: string;
if (this.tokenService.tokenNeedsRefresh()) {
const tokenResponse = await this.doRefreshToken();
accessToken = tokenResponse.accessToken;
} else {
accessToken = await this.tokenService.getToken();
}
return 'Bearer ' + accessToken;
}
private async doRefreshToken(): Promise<IdentityTokenResponse> {
const refreshToken = await this.tokenService.getRefreshToken();
if (refreshToken == null || refreshToken === '') {
throw new Error();
}
const response = await fetch(new Request(this.identityBaseUrl + '/connect/token', {
body: this.qsStringify({
grant_type: 'refresh_token',
client_id: 'browser',
refresh_token: refreshToken,
}),
cache: 'no-cache',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'Accept': 'application/json',
'Device-Type': this.deviceType,
}),
method: 'POST',
}));
if (response.status === 200) {
const responseJson = await response.json();
const tokenResponse = new IdentityTokenResponse(responseJson);
await this.tokenService.setTokens(tokenResponse.accessToken, tokenResponse.refreshToken);
return tokenResponse;
} else {
const error = await this.handleError(response, true);
return Promise.reject(error);
}
}
private qsStringify(params: any): string {
return Object.keys(params).map((key) => {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
}
}

View File

@ -1,27 +0,0 @@
import { UtilsService } from 'jslib/services';
import { StorageService } from 'jslib/abstractions';
export default class AppIdService {
constructor(private storageService: StorageService) {
}
getAppId(): Promise<string> {
return this.makeAndGetAppId('appId');
}
getAnonymousAppId(): Promise<string> {
return this.makeAndGetAppId('anonymousAppId');
}
private async makeAndGetAppId(key: string) {
const existingId = await this.storageService.get<string>(key);
if (existingId != null) {
return existingId;
}
const guid = UtilsService.newGuid();
await this.storageService.save(key, guid);
return guid;
}
}

View File

@ -8,13 +8,13 @@ import AutofillPageDetails from '../models/domain/autofillPageDetails';
import AutofillScript from '../models/domain/autofillScript'; import AutofillScript from '../models/domain/autofillScript';
import CipherService from './cipher.service'; import CipherService from './cipher.service';
import TokenService from './token.service';
import TotpService from './totp.service'; import TotpService from './totp.service';
import { UtilsService } from 'jslib/services'; import { UtilsService } from 'jslib/services';
import { import {
PlatformUtilsService, PlatformUtilsService,
TokenService,
UtilsService as UtilsServiceAbstraction, UtilsService as UtilsServiceAbstraction,
} from 'jslib/abstractions'; } from 'jslib/abstractions';

View File

@ -17,11 +17,11 @@ import {
} from 'jslib/models/response'; } from 'jslib/models/response';
import { import {
ApiService,
CryptoService, CryptoService,
StorageService, StorageService,
} from 'jslib/abstractions'; } from 'jslib/abstractions';
import ApiService from './api.service';
import ConstantsService from './constants.service'; import ConstantsService from './constants.service';
import SettingsService from './settings.service'; import SettingsService from './settings.service';
import UserService from './user.service'; import UserService from './user.service';

View File

@ -1,9 +1,11 @@
import ApiService from './api.service';
import ConstantsService from './constants.service'; import ConstantsService from './constants.service';
import { EnvironmentUrls } from 'jslib/models/domain'; import { EnvironmentUrls } from 'jslib/models/domain';
import { StorageService } from 'jslib/abstractions'; import {
ApiService,
StorageService,
} from 'jslib/abstractions';
export default class EnvironmentService { export default class EnvironmentService {
baseUrl: string; baseUrl: string;

View File

@ -1,4 +1,3 @@
import ApiService from './api.service';
import UserService from './user.service'; import UserService from './user.service';
import { FolderData } from 'jslib/models/data'; import { FolderData } from 'jslib/models/data';
@ -10,6 +9,7 @@ import { FolderRequest } from 'jslib/models/request';
import { FolderResponse } from 'jslib/models/response'; import { FolderResponse } from 'jslib/models/response';
import { import {
ApiService,
CryptoService, CryptoService,
StorageService, StorageService,
} from 'jslib/abstractions'; } from 'jslib/abstractions';

View File

@ -1,4 +1,3 @@
import ApiService from './api.service';
import CipherService from './cipher.service'; import CipherService from './cipher.service';
import CollectionService from './collection.service'; import CollectionService from './collection.service';
import FolderService from './folder.service'; import FolderService from './folder.service';
@ -6,6 +5,7 @@ import SettingsService from './settings.service';
import UserService from './user.service'; import UserService from './user.service';
import { import {
ApiService,
CryptoService, CryptoService,
MessagingService, MessagingService,
StorageService, StorageService,

View File

@ -1,176 +0,0 @@
import ConstantsService from './constants.service';
import { UtilsService } from 'jslib/services/utils.service';
import { StorageService } from 'jslib/abstractions';
const Keys = {
accessToken: 'accessToken',
refreshToken: 'refreshToken',
twoFactorTokenPrefix: 'twoFactorToken_',
};
export default class TokenService {
token: string;
decodedToken: any;
refreshToken: string;
constructor(private storageService: StorageService) {
}
setTokens(accessToken: string, refreshToken: string): Promise<any> {
return Promise.all([
this.setToken(accessToken),
this.setRefreshToken(refreshToken),
]);
}
setToken(token: string): Promise<any> {
this.token = token;
this.decodedToken = null;
return this.storageService.save(Keys.accessToken, token);
}
async getToken(): Promise<string> {
if (this.token != null) {
return this.token;
}
this.token = await this.storageService.get<string>(Keys.accessToken);
return this.token;
}
setRefreshToken(refreshToken: string): Promise<any> {
this.refreshToken = refreshToken;
return this.storageService.save(Keys.refreshToken, refreshToken);
}
async getRefreshToken(): Promise<string> {
if (this.refreshToken != null) {
return this.refreshToken;
}
this.refreshToken = await this.storageService.get<string>(Keys.refreshToken);
return this.refreshToken;
}
setTwoFactorToken(token: string, email: string): Promise<any> {
return this.storageService.save(Keys.twoFactorTokenPrefix + email, token);
}
getTwoFactorToken(email: string): Promise<string> {
return this.storageService.get<string>(Keys.twoFactorTokenPrefix + email);
}
clearTwoFactorToken(email: string): Promise<any> {
return this.storageService.remove(Keys.twoFactorTokenPrefix + email);
}
clearToken(): Promise<any> {
this.token = null;
this.decodedToken = null;
this.refreshToken = null;
return Promise.all([
this.storageService.remove(Keys.accessToken),
this.storageService.remove(Keys.refreshToken),
]);
}
// jwthelper methods
// ref https://github.com/auth0/angular-jwt/blob/master/src/angularJwt/services/jwt.js
decodeToken(): any {
if (this.decodedToken) {
return this.decodedToken;
}
if (this.token == null) {
throw new Error('Token not found.');
}
const parts = this.token.split('.');
if (parts.length !== 3) {
throw new Error('JWT must have 3 parts');
}
const decoded = UtilsService.urlBase64Decode(parts[1]);
if (decoded == null) {
throw new Error('Cannot decode the token');
}
this.decodedToken = JSON.parse(decoded);
return this.decodedToken;
}
getTokenExpirationDate(): Date {
const decoded = this.decodeToken();
if (typeof decoded.exp === 'undefined') {
return null;
}
const d = new Date(0); // The 0 here is the key, which sets the date to the epoch
d.setUTCSeconds(decoded.exp);
return d;
}
tokenSecondsRemaining(offsetSeconds: number = 0): number {
const d = this.getTokenExpirationDate();
if (d == null) {
return 0;
}
const msRemaining = d.valueOf() - (new Date().valueOf() + (offsetSeconds * 1000));
return Math.round(msRemaining / 1000);
}
tokenNeedsRefresh(minutes: number = 5): boolean {
const sRemaining = this.tokenSecondsRemaining();
return sRemaining < (60 * minutes);
}
getUserId(): string {
const decoded = this.decodeToken();
if (typeof decoded.sub === 'undefined') {
throw new Error('No user id found');
}
return decoded.sub as string;
}
getEmail(): string {
const decoded = this.decodeToken();
if (typeof decoded.email === 'undefined') {
throw new Error('No email found');
}
return decoded.email as string;
}
getName(): string {
const decoded = this.decodeToken();
if (typeof decoded.name === 'undefined') {
throw new Error('No name found');
}
return decoded.name as string;
}
getPremium(): boolean {
const decoded = this.decodeToken();
if (typeof decoded.premium === 'undefined') {
return false;
}
return decoded.premium as boolean;
}
getIssuer(): string {
const decoded = this.decodeToken();
if (typeof decoded.iss === 'undefined') {
throw new Error('No issuer found');
}
return decoded.iss as string;
}
}

View File

@ -1,6 +1,4 @@
import TokenService from './token.service'; import { StorageService, TokenService } from 'jslib/abstractions';
import { StorageService } from 'jslib/abstractions';
const Keys = { const Keys = {
userId: 'userId', userId: 'userId',