Skip to content

fix(#160) : changed AuthHttpError to Error #187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions angular2-jwt.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "core-js";
import {AuthConfig, AuthHttp, tokenNotExpired, JwtHelper} from "./angular2-jwt";
import {AuthConfig, AuthHttp, tokenNotExpired, JwtHelper, AuthHttpError} from "./angular2-jwt";
import {Observable} from "rxjs";
import {Base64} from "js-base64";

Expand Down Expand Up @@ -173,4 +173,26 @@ describe("AuthHttp", () => {
});
});
});
});
});

describe("AuthHttpError", () => {

'use strict';

it("constructor fails to set the error message", () => {
const message = 'This is an error';
let error = new AuthHttpError(message);
expect(error.message).toBe('');
});
});

describe("Error", () => {

'use strict';

it("constructor should set the error message", () => {
const message = 'This is an error';
let error = new Error(message);
expect(error.message).toBe(message);
});
});
2 changes: 1 addition & 1 deletion angular2-jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export class AuthHttp {
if (!tokenNotExpired(undefined, token)) {
if (!this.config.noJwtError) {
return new Observable<Response>((obs: any) => {
obs.error(new AuthHttpError('No JWT present or has expired'));
obs.error(new Error('No JWT present or has expired'));
});
}
} else {
Expand Down
12 changes: 6 additions & 6 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ module.exports = function (config) {
frameworks: ["jasmine"],
// list of files / patterns to load in the browser
files: [
{pattern: 'angular2-jwt.spec.ts', watched: false}
{pattern: '*.spec.ts', watched: false}
],

// list of files / patterns to exclude
exclude: [],

preprocessors: {
'angular2-jwt.spec.ts': [ 'webpack', 'sourcemap']
'*.spec.ts': [ 'webpack', 'sourcemap']
},


Expand All @@ -35,18 +35,18 @@ module.exports = function (config) {
logLevel: config.LOG_INFO,

// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
autoWatch: true,

browsers: [
//"Firefox",
//"Chrome",
"Chrome",
//"IE",
"PhantomJS"
//"PhantomJS"
],

// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: true,
singleRun: false,

reporters: ['progress'],

Expand Down
110 changes: 110 additions & 0 deletions token.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Token } from "./token";
import { Base64 } from 'js-base64';

const expiredToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjB9.m2OKoK5-Fnbbg4inMrsAQKsehq2wpQYim8695uLdogk";
const validToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjk5OTk5OTk5OTl9.K_lUwtGbvjCHP8Ff-gW9GykydkkXzHKRPbACxItvrFU";
const noExpiryToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
const tokenFormatString = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.{0}.m2OKoK5-Fnbbg4inMrsAQKsehq2wpQYim8695uLdogk";


describe("Token", () => {

'use strict';

it("constructor with null value should throw", () => {
let createToken = function () { new Token(null); };
expect(createToken).toThrow();
});

it("constructor with invalid format value should throw", () => {
let createToken = function () { new Token('InvalidFormat'); };
expect(createToken).toThrow();
});

it("constructor with blank value should throw", () => {
let createToken = function () { new Token(''); };
expect(createToken).toThrow();
});

it("with same value are equal", () => {
let token1 = new Token(expiredToken);
let token2 = new Token(expiredToken);
expect(token1.equals(token2)).toBe(true);
});

it("with different value are not equal", () => {
let token1 = new Token(expiredToken);
let token2 = new Token(noExpiryToken);
expect(token1.equals(token2)).toBe(false);
});

it("null is not a token", () => {
expect(Token.isToken(null)).toBe(false);
});

it("blank string is not a token", () => {
expect(Token.isToken('')).toBe(false);
});

it("null is not a token", () => {
expect(Token.isToken(null)).toBe(false);
});

it("validtoken is a token", () => {
expect(Token.isToken(validToken)).toBe(true);
});

describe("Payload", () => {

const unexpiredObject = { name: "angular2", exp: 9999999999 };
const expiredObject = { name: "angular2", exp: 10 };
const expirelessObject = { name: "angular2" };

it("with expireless instance should decode", () => {
//arrange
let ePayload = Base64.encode(JSON.stringify(expirelessObject));
let tokenValue = tokenFormatString.replace('{0}', ePayload);
const token = new Token(tokenValue);

//act
let payload = token.decodePayLoad();

//assert
expect(payload.name).toBe(expirelessObject.name);
expect(payload.exp).toBeUndefined();
expect(payload.getExpirationDate()).toBe(null);
expect(payload.isExpired()).toBe(false);
});

it("with unexpired instance should decode", () => {
let encoded = Base64.encode(JSON.stringify(unexpiredObject));
let tokenValue = tokenFormatString.replace('{0}', encoded);
const token = new Token(tokenValue);

//act
let payload = token.decodePayLoad();

//assert
expect(payload.name).toBe(unexpiredObject.name);
expect(payload.exp).toBe(unexpiredObject.exp);
expect(payload.isExpired()).toBe(false);
});

it("with expired instance should decode", () => {
let encoded = Base64.encode(JSON.stringify(expiredObject));
let tokenValue = tokenFormatString.replace('{0}', encoded);
const token: Token = new Token(tokenValue);

//act
let payload = token.decodePayLoad();

//assert
expect(payload.name).toBe(expiredObject.name);
expect(payload.exp).toBe(expiredObject.exp);
expect(payload.isExpired()).toBe(true);
});

});

});

82 changes: 82 additions & 0 deletions token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {JwtHelper} from "./angular2-jwt";

export class Token {

private _value: string = null;
private _payload: IPayload = null;

public get value(): string {
return this._value;
}

constructor(value: string) {

Token._decodeInternal(value);
this._value = value;
}

public static isToken(value: string): boolean {
try {
Token._decodeInternal(value);
return true;
}
catch (e) {
};
return false;
}

public equals(token: Token): boolean {
if (token.value === this.value) return true;
return false;
}

public decodePayLoad(): any {
return this._payload = this._payload || Token._decodeInternal(this._value);
}

private static _decodeInternal(value: string): IPayload {

let parts = value.split('.');

if (parts.length !== 3) {
throw new Error('Failed to decode. A JWT token must contain 3 parts.');
}

let decoded = new JwtHelper().urlBase64Decode(parts[1]);
if (!decoded) {
throw new Error('Failed to decode. The token must be base64 encoded.');
}

var instance = JSON.parse(decoded);
this.makePayLoadImplementation(instance);
return instance;
}

private static makePayLoadImplementation(instance: any) {
instance.getExpirationDate = function() {
if (!instance.hasOwnProperty('exp')) {
return null;
}
let date = new Date(0); // The 0 here is the key, which sets the date to the epoch
date.setUTCSeconds(instance.exp);

return date;
};
instance.isExpired = function(offsetSeconds?: number) {
let date = instance.getExpirationDate();
offsetSeconds = offsetSeconds || 0;

if (date == null) {
return false;
}

// Token expired?
return !(date.valueOf() > (new Date().valueOf() + (offsetSeconds * 1000)));
};
};
}

interface IPayload {
exp: string;
getExpirationDate(): boolean;
}
2 changes: 2 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"files": [
"angular2-jwt.ts",
"angular2-jwt.spec.ts",
"token.ts",
"token.spec.ts",
"custom.d.ts"
],
"exclude": [
Expand Down