commit
4e0b2881c3
|
@ -5,10 +5,10 @@ module.exports = function (grunt) {
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
env: {
|
env: {
|
||||||
"env-test-server-unit": {
|
"env-test-server-unit": {
|
||||||
TS_NODE_PROJECT: "server"
|
TS_NODE_PROJECT: "server/tsconfig.json"
|
||||||
},
|
},
|
||||||
"env-test-client-unit": {
|
"env-test-client-unit": {
|
||||||
TS_NODE_PROJECT: "client"
|
TS_NODE_PROJECT: "client/tsconfig.json"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
run: {
|
run: {
|
||||||
|
@ -180,8 +180,8 @@ module.exports = function (grunt) {
|
||||||
grunt.registerTask('compile-server', ['run:lint-server', 'run:compile-server'])
|
grunt.registerTask('compile-server', ['run:lint-server', 'run:compile-server'])
|
||||||
grunt.registerTask('compile-client', ['run:lint-client', 'run:compile-client'])
|
grunt.registerTask('compile-client', ['run:lint-client', 'run:compile-client'])
|
||||||
|
|
||||||
grunt.registerTask('test-server', ['run:test-server-unit'])
|
grunt.registerTask('test-server', ['env:env-test-server-unit', 'run:test-server-unit'])
|
||||||
grunt.registerTask('test-client', ['run:test-client-unit'])
|
grunt.registerTask('test-client', ['env:env-test-client-unit', 'run:test-client-unit'])
|
||||||
grunt.registerTask('test-unit', ['test-server', 'test-client']);
|
grunt.registerTask('test-unit', ['test-server', 'test-client']);
|
||||||
grunt.registerTask('test-int', ['run:test-int']);
|
grunt.registerTask('test-int', ['run:test-int']);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -78,6 +78,7 @@
|
||||||
"@types/request-promise": "^4.1.38",
|
"@types/request-promise": "^4.1.38",
|
||||||
"@types/selenium-webdriver": "^3.0.4",
|
"@types/selenium-webdriver": "^3.0.4",
|
||||||
"@types/sinon": "^4.3.0",
|
"@types/sinon": "^4.3.0",
|
||||||
|
"@types/speakeasy": "^2.0.2",
|
||||||
"@types/tmp": "0.0.33",
|
"@types/tmp": "0.0.33",
|
||||||
"@types/winston": "^2.3.2",
|
"@types/winston": "^2.3.2",
|
||||||
"@types/yamljs": "^0.2.30",
|
"@types/yamljs": "^0.2.30",
|
||||||
|
@ -109,12 +110,12 @@
|
||||||
"request-promise": "^4.2.2",
|
"request-promise": "^4.2.2",
|
||||||
"selenium-webdriver": "^4.0.0-alpha.1",
|
"selenium-webdriver": "^4.0.0-alpha.1",
|
||||||
"should": "^13.2.1",
|
"should": "^13.2.1",
|
||||||
"sinon": "^4.0.2",
|
"sinon": "^5.0.7",
|
||||||
"tmp": "0.0.33",
|
"tmp": "0.0.33",
|
||||||
"ts-node": "^5.0.1",
|
"ts-node": "^6.0.1",
|
||||||
"tslint": "^5.2.0",
|
"tslint": "^5.2.0",
|
||||||
"typescript": "^2.3.2",
|
"typescript": "^2.3.2",
|
||||||
"typescript-json-schema": "^0.21.0",
|
"typescript-json-schema": "^0.23.0",
|
||||||
"uglify-es": "^3.0.15"
|
"uglify-es": "^3.0.15"
|
||||||
},
|
},
|
||||||
"nyc": {
|
"nyc": {
|
||||||
|
|
|
@ -3,7 +3,7 @@ export class LdapSearchError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "LdapSearchError";
|
this.name = "LdapSearchError";
|
||||||
Object.setPrototypeOf(this, LdapSearchError.prototype);
|
(<any>Object).setPrototypeOf(this, LdapSearchError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ export class LdapBindError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "LdapBindError";
|
this.name = "LdapBindError";
|
||||||
Object.setPrototypeOf(this, LdapBindError.prototype);
|
(<any>Object).setPrototypeOf(this, LdapBindError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ export class LdapError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "LdapError";
|
this.name = "LdapError";
|
||||||
Object.setPrototypeOf(this, LdapError.prototype);
|
(<any>Object).setPrototypeOf(this, LdapError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ export class IdentityError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "IdentityError";
|
this.name = "IdentityError";
|
||||||
Object.setPrototypeOf(this, IdentityError.prototype);
|
(<any>Object).setPrototypeOf(this, IdentityError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export class AccessDeniedError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "AccessDeniedError";
|
this.name = "AccessDeniedError";
|
||||||
Object.setPrototypeOf(this, AccessDeniedError.prototype);
|
(<any>Object).setPrototypeOf(this, AccessDeniedError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ export class AuthenticationRegulationError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "AuthenticationRegulationError";
|
this.name = "AuthenticationRegulationError";
|
||||||
Object.setPrototypeOf(this, AuthenticationRegulationError.prototype);
|
(<any>Object).setPrototypeOf(this, AuthenticationRegulationError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ export class InvalidTOTPError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "InvalidTOTPError";
|
this.name = "InvalidTOTPError";
|
||||||
Object.setPrototypeOf(this, InvalidTOTPError.prototype);
|
(<any>Object).setPrototypeOf(this, InvalidTOTPError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export class DomainAccessDenied extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "DomainAccessDenied";
|
this.name = "DomainAccessDenied";
|
||||||
Object.setPrototypeOf(this, DomainAccessDenied.prototype);
|
(<any>Object).setPrototypeOf(this, DomainAccessDenied.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ export class FirstFactorValidationError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "FirstFactorValidationError";
|
this.name = "FirstFactorValidationError";
|
||||||
Object.setPrototypeOf(this, FirstFactorValidationError.prototype);
|
(<any>Object).setPrototypeOf(this, FirstFactorValidationError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,6 @@ export class SecondFactorValidationError extends Error {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "SecondFactorValidationError";
|
this.name = "SecondFactorValidationError";
|
||||||
Object.setPrototypeOf(this, FirstFactorValidationError.prototype);
|
(<any>Object).setPrototypeOf(this, FirstFactorValidationError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -49,9 +49,9 @@ describe("test identity check process", function () {
|
||||||
|
|
||||||
mocks.notifier.notifyStub.returns(BluebirdPromise.resolve());
|
mocks.notifier.notifyStub.returns(BluebirdPromise.resolve());
|
||||||
mocks.userDataStore.produceIdentityValidationTokenStub
|
mocks.userDataStore.produceIdentityValidationTokenStub
|
||||||
.returns(Promise.resolve());
|
.returns(BluebirdPromise.resolve());
|
||||||
mocks.userDataStore.consumeIdentityValidationTokenStub
|
mocks.userDataStore.consumeIdentityValidationTokenStub
|
||||||
.returns(Promise.resolve({ userId: "user" }));
|
.returns(BluebirdPromise.resolve({ userId: "user" }));
|
||||||
|
|
||||||
app = express();
|
app = express();
|
||||||
app_get = sinon.stub(app, "get");
|
app_get = sinon.stub(app, "get");
|
||||||
|
|
|
@ -10,36 +10,34 @@ import session = require("express-session");
|
||||||
import { AppConfiguration, UserConfiguration } from "../src/lib/configuration/Configuration";
|
import { AppConfiguration, UserConfiguration } from "../src/lib/configuration/Configuration";
|
||||||
import { GlobalDependencies } from "../types/Dependencies";
|
import { GlobalDependencies } from "../types/Dependencies";
|
||||||
import Server from "../src/lib/Server";
|
import Server from "../src/lib/Server";
|
||||||
|
import { LdapjsMock, LdapjsClientMock } from "./mocks/ldapjs";
|
||||||
|
|
||||||
|
|
||||||
describe("test server configuration", function () {
|
describe("test server configuration", function () {
|
||||||
let deps: GlobalDependencies;
|
let deps: GlobalDependencies;
|
||||||
let sessionMock: Sinon.SinonSpy;
|
let sessionMock: Sinon.SinonSpy;
|
||||||
|
let ldapjsMock: LdapjsMock;
|
||||||
|
|
||||||
before(function () {
|
before(function () {
|
||||||
sessionMock = Sinon.spy(session);
|
sessionMock = Sinon.spy(session);
|
||||||
|
ldapjsMock = new LdapjsMock();
|
||||||
|
|
||||||
deps = {
|
deps = {
|
||||||
speakeasy: speakeasy,
|
speakeasy: speakeasy,
|
||||||
u2f: u2f,
|
u2f: u2f,
|
||||||
nedb: nedb,
|
nedb: nedb,
|
||||||
winston: winston,
|
winston: winston,
|
||||||
ldapjs: {
|
ldapjs: ldapjsMock as any,
|
||||||
createClient: Sinon.spy(function () {
|
|
||||||
return {
|
|
||||||
on: Sinon.spy(),
|
|
||||||
bind: Sinon.spy(),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
},
|
|
||||||
session: sessionMock as any,
|
session: sessionMock as any,
|
||||||
ConnectRedis: Sinon.spy()
|
ConnectRedis: Sinon.spy(),
|
||||||
|
Redis: Sinon.spy() as any
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("should set cookie scope to domain set in the config", function () {
|
it("should set cookie scope to domain set in the config", function () {
|
||||||
const config: UserConfiguration = {
|
const config: UserConfiguration = {
|
||||||
|
port: 8081,
|
||||||
session: {
|
session: {
|
||||||
domain: "example.com",
|
domain: "example.com",
|
||||||
secret: "secret"
|
secret: "secret"
|
||||||
|
|
|
@ -65,7 +65,8 @@ describe("test session configuration builder", function () {
|
||||||
session: Sinon.spy() as any,
|
session: Sinon.spy() as any,
|
||||||
speakeasy: Sinon.spy() as any,
|
speakeasy: Sinon.spy() as any,
|
||||||
u2f: Sinon.spy() as any,
|
u2f: Sinon.spy() as any,
|
||||||
winston: Sinon.spy() as any
|
winston: Sinon.spy() as any,
|
||||||
|
Redis: Sinon.spy() as any
|
||||||
};
|
};
|
||||||
|
|
||||||
const options = SessionConfigurationBuilder.build(configuration, deps);
|
const options = SessionConfigurationBuilder.build(configuration, deps);
|
||||||
|
|
|
@ -1,30 +1,50 @@
|
||||||
|
|
||||||
import sinon = require("sinon");
|
import Sinon = require("sinon");
|
||||||
|
|
||||||
export interface LdapjsMock {
|
export class LdapjsMock {
|
||||||
createClient: sinon.SinonStub;
|
createClientStub: sinon.SinonStub;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.createClientStub = Sinon.stub();
|
||||||
|
}
|
||||||
|
|
||||||
|
createClient(params: any) {
|
||||||
|
return this.createClientStub(params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LdapjsClientMock {
|
export class LdapjsClientMock {
|
||||||
bind: sinon.SinonStub;
|
bindStub: sinon.SinonStub;
|
||||||
unbind: sinon.SinonStub;
|
unbindStub: sinon.SinonStub;
|
||||||
search: sinon.SinonStub;
|
searchStub: sinon.SinonStub;
|
||||||
modify: sinon.SinonStub;
|
modifyStub: sinon.SinonStub;
|
||||||
on: sinon.SinonStub;
|
onStub: sinon.SinonStub;
|
||||||
}
|
|
||||||
|
|
||||||
export function LdapjsMock(): LdapjsMock {
|
constructor() {
|
||||||
return {
|
this.bindStub = Sinon.stub();
|
||||||
createClient: sinon.stub()
|
this.unbindStub = Sinon.stub();
|
||||||
};
|
this.searchStub = Sinon.stub();
|
||||||
}
|
this.modifyStub = Sinon.stub();
|
||||||
|
this.onStub = Sinon.stub();
|
||||||
|
}
|
||||||
|
|
||||||
export function LdapjsClientMock(): LdapjsClientMock {
|
bind() {
|
||||||
return {
|
return this.bindStub();
|
||||||
bind: sinon.stub(),
|
}
|
||||||
unbind: sinon.stub(),
|
|
||||||
search: sinon.stub(),
|
unbind() {
|
||||||
modify: sinon.stub(),
|
return this.unbindStub();
|
||||||
on: sinon.stub()
|
}
|
||||||
};
|
|
||||||
|
search() {
|
||||||
|
return this.searchStub();
|
||||||
|
}
|
||||||
|
|
||||||
|
modify() {
|
||||||
|
return this.modifyStub();
|
||||||
|
}
|
||||||
|
|
||||||
|
on() {
|
||||||
|
return this.onStub();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@ import { IMongoClient } from "../../../server/src/lib/connectors/mongo/IMongoCli
|
||||||
import { TotpHandler } from "../../../server/src/lib/authentication/totp/TotpHandler";
|
import { TotpHandler } from "../../../server/src/lib/authentication/totp/TotpHandler";
|
||||||
import Speakeasy = require("speakeasy");
|
import Speakeasy = require("speakeasy");
|
||||||
import Request = require("request-promise");
|
import Request = require("request-promise");
|
||||||
|
import { TOTPSecret } from "../../../server/types/TOTPSecret";
|
||||||
|
|
||||||
setDefaultTimeout(20 * 1000);
|
setDefaultTimeout(20 * 1000);
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ declareNeedsConfiguration("single_factor", createSingleFactorConfiguration);
|
||||||
declareNeedsConfiguration("totp_issuer", createCustomTotpIssuerConfiguration);
|
declareNeedsConfiguration("totp_issuer", createCustomTotpIssuerConfiguration);
|
||||||
|
|
||||||
function registerUser(context: any, username: string) {
|
function registerUser(context: any, username: string) {
|
||||||
let secret: Speakeasy.Key;
|
let secret: TOTPSecret;
|
||||||
const mongoConnector = new MongoConnector("mongodb://localhost:27017");
|
const mongoConnector = new MongoConnector("mongodb://localhost:27017");
|
||||||
return mongoConnector.connect("authelia")
|
return mongoConnector.connect("authelia")
|
||||||
.then(function (mongoClient: IMongoClient) {
|
.then(function (mongoClient: IMongoClient) {
|
||||||
|
|
Loading…
Reference in New Issue