| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 | 
							- const jwt = require("jsonwebtoken");
 
- const assert = require("assert");
 
- const koajwt = require("../lib");
 
- const UnauthorizedError = require("../lib/errors/UnauthorizedError");
 
- const mockContext = require("./context");
 
- describe("failure tests", function() {
 
-   let ctx;
 
-   beforeEach(() => {
 
-     ctx = mockContext();
 
-   });
 
-   it("should throw if options not sent", function() {
 
-     try {
 
-       koajwt();
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.message, "secret should be set");
 
-     }
 
-   });
 
-   it("should throw if no authorization header and credentials are required", async () => {
 
-     try {
 
-       await koajwt({ secret: "shhhh", credentialsRequired: true })(
 
-         ctx,
 
-         () => {}
 
-       );
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "credentials_required");
 
-     }
 
-   });
 
-   it("support unless skip", async () => {
 
-     ctx.req.url = "/index.html";
 
-     await koajwt({ secret: "shhhh" }).unless({
 
-       path: "/index.html",
 
-       useOriginalUrl: false
 
-     })(ctx, () => {});
 
-     assert.ok(true);
 
-   });
 
-   it("should skip on CORS preflight", async () => {
 
-     ctx.req.method = "OPTIONS";
 
-     ctx.req.headers = {
 
-       "access-control-request-headers": "sasa, sras,  authorization"
 
-     };
 
-     await koajwt({ secret: "shhhh" })(ctx, () => {});
 
-     assert.ok(true);
 
-   });
 
-   it("should throw if authorization header is malformed", async () => {
 
-     ctx.headers.authorization = "wrong";
 
-     try {
 
-       await koajwt({ secret: "shhhh" })(ctx, () => {});
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "credentials_bad_format");
 
-     }
 
-   });
 
-   it("should throw if authorization header is not Bearer", async () => {
 
-     ctx.headers.authorization = "Basic foobar";
 
-     try {
 
-       await koajwt({ secret: "shhhh" })(ctx, () => {});
 
-     } catch (err) {
 
-       assert.equal(err.code, "credentials_bad_scheme");
 
-     }
 
-   });
 
-   it("should next if authorization header is not Bearer and credentialsRequired is false", async () => {
 
-     ctx.headers.authorization = "Basic foobar";
 
-     await koajwt({ secret: "shhhh", credentialsRequired: false })(
 
-       ctx,
 
-       () => {}
 
-     );
 
-     assert.ok(true);
 
-   });
 
-   it("should throw if authorization header is not well-formatted jwt", async () => {
 
-     ctx.headers.authorization = "Bearer wrongjwt";
 
-     try {
 
-       await koajwt({ secret: "shhhh" })(ctx, () => {});
 
-     } catch (err) {
 
-       assert.equal(err.code, "invalid_token");
 
-     }
 
-   });
 
-   it("should throw if jwt is an invalid json", async () => {
 
-     ctx.headers.authorization =
 
-       "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.yJ1c2VybmFtZSI6InNhZ3VpYXIiLCJpYXQiOjE0NzEwMTg2MzUsImV4cCI6MTQ3MzYxMDYzNX0.foo";
 
-     try {
 
-       await koajwt({ secret: "shhhh" })(ctx, () => {});
 
-     } catch (err) {
 
-       assert.equal(err.code, "invalid_token");
 
-     }
 
-   });
 
-   it("should throw if authorization header is not valid jwt", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar" }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     try {
 
-       await koajwt({ secret: "different-shhhh" })(ctx, () => {});
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "invalid_token");
 
-       assert.equal(err.message, "invalid signature");
 
-     }
 
-   });
 
-   it("should throw if audience is not expected", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar", aud: "expected-audience" }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     try {
 
-       await koajwt({ secret: "shhhhhh", audience: "not-expected-audience" })(
 
-         ctx,
 
-         () => {}
 
-       );
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "invalid_token");
 
-       assert.equal(
 
-         err.message,
 
-         "jwt audience invalid. expected: not-expected-audience"
 
-       );
 
-     }
 
-   });
 
-   it("should throw if token is expired", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar", exp: 1382412921 }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     try {
 
-       await koajwt({ secret: "shhhhhh" })(ctx, () => {});
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "invalid_token");
 
-       assert.equal(err.inner.name, "TokenExpiredError");
 
-       assert.equal(err.message, "jwt expired");
 
-     }
 
-   });
 
-   it("should throw if token issuer is wrong", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar", iss: "http://foo" }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     try {
 
-       await koajwt({ secret: "shhhhhh", issuer: "http://wrong" })(
 
-         ctx,
 
-         () => {}
 
-       );
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "invalid_token");
 
-       assert.equal(err.message, "jwt issuer invalid. expected: http://wrong");
 
-     }
 
-   });
 
-   it("should use errors thrown from custom getToken function", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar" }, secret);
 
-     function getTokenThatThrowsError() {
 
-       throw new UnauthorizedError("invalid_token", {
 
-         message: "Invalid token!"
 
-       });
 
-     }
 
-     try {
 
-       await koajwt({
 
-         secret: "shhhhhh",
 
-         getToken: getTokenThatThrowsError
 
-       })(ctx, () => {});
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "invalid_token");
 
-       assert.equal(err.message, "Invalid token!");
 
-     }
 
-   });
 
-   it("should throw error when signature is wrong", async () => {
 
-     const secret = "shhh";
 
-     const token = jwt.sign({ foo: "bar", iss: "http://www" }, secret);
 
-     // manipulate the token
 
-     const newContent = new Buffer("{foo: 'bar', edg: 'ar'}").toString("base64");
 
-     const splitetToken = token.split(".");
 
-     splitetToken[1] = newContent;
 
-     const newToken = splitetToken.join(".");
 
-     // build request
 
-     ctx.headers = [];
 
-     ctx.headers.authorization = "Bearer " + newToken;
 
-     try {
 
-       await koajwt({ secret: secret })(ctx, () => {});
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "invalid_token");
 
-       assert.equal(err.message, "invalid token");
 
-     }
 
-   });
 
-   it("should throw error if token is expired even with when credentials are not required", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar", exp: 1382412921 }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     try {
 
-       await koajwt({ secret: secret, credentialsRequired: false })(
 
-         ctx,
 
-         () => {}
 
-       );
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "invalid_token");
 
-       assert.equal(err.message, "jwt expired");
 
-     }
 
-   });
 
-   it("should throw error if token is invalid even with when credentials are not required", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar", exp: 1382412921 }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     try {
 
-       await koajwt({ secret: "not the secret", credentialsRequired: false })(
 
-         ctx,
 
-         () => {}
 
-       );
 
-     } catch (err) {
 
-       assert.ok(err);
 
-       assert.equal(err.code, "invalid_token");
 
-       assert.equal(err.message, "invalid signature");
 
-     }
 
-   });
 
- });
 
- describe("work tests", function() {
 
-   let ctx;
 
-   beforeEach(() => {
 
-     ctx = mockContext();
 
-   });
 
-   it("should work if authorization header is valid jwt", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar" }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     await koajwt({ secret })(ctx, () => {});
 
-     assert.equal("bar", ctx.state.user.foo);
 
-   });
 
-   it("should work with nested properties", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar" }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     await koajwt({ secret, property: "auth.token" })(ctx, () => {});
 
-     assert.equal("bar", ctx.state.auth.token.foo);
 
-   });
 
-   it("should work if authorization header is valid with a buffer secret", async () => {
 
-     const secret = new Buffer(
 
-       "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
 
-       "base64"
 
-     );
 
-     const token = jwt.sign({ foo: "bar" }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     await koajwt({ secret })(ctx, () => {});
 
-     assert.equal("bar", ctx.state.user.foo);
 
-   });
 
-   it("should set property if option provided", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar" }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     await koajwt({ secret, property: "auth" })(ctx, () => {});
 
-     assert.equal("bar", ctx.state.auth.foo);
 
-   });
 
-   it("should work if no authorization header and credentials are not required", async () => {
 
-     await koajwt({ secret: "shhhh", credentialsRequired: false })(
 
-       ctx,
 
-       () => {}
 
-     );
 
-     assert.ok(true);
 
-   });
 
-   it("should not work if no authorization header", async () => {
 
-     try {
 
-       await koajwt({ secret: "shhhh" })(ctx, () => {});
 
-     } catch (err) {
 
-       assert(typeof err !== "undefined");
 
-     }
 
-   });
 
-   it("should produce a stack trace that includes the failure reason", async () => {
 
-     const token = jwt.sign({ foo: "bar" }, "secretA");
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     try {
 
-       await koajwt({ secret: "secretB" })(ctx, () => {});
 
-     } catch (err) {
 
-       const index = err.stack.indexOf("UnauthorizedError: invalid signature");
 
-       assert.equal(
 
-         index,
 
-         0,
 
-         "Stack trace didn't include 'invalid signature' message."
 
-       );
 
-     }
 
-   });
 
-   it("should work with a custom getToken function", async () => {
 
-     const secret = "shhhhhh";
 
-     const token = jwt.sign({ foo: "bar" }, secret);
 
-     ctx.query = {
 
-       token
 
-     };
 
-     function getTokenFromQuery(ctx) {
 
-       return ctx.query.token;
 
-     }
 
-     await koajwt({
 
-       secret,
 
-       getToken: getTokenFromQuery
 
-     })(ctx, () => {
 
-       assert.equal("bar", ctx.state.user.foo);
 
-     });
 
-   });
 
-   it("should work with a secret async function that accepts header argument", async () => {
 
-     const secret = "shhhhhh";
 
-     const secretAsync = async function(ctx, headers, payload, cb) {
 
-       assert.equal(headers.alg, "HS256");
 
-       assert.equal(payload.foo, "bar");
 
-       return new Promise(resolve => {
 
-         process.nextTick(function() {
 
-           resolve(secret);
 
-         });
 
-       });
 
-     };
 
-     const token = jwt.sign({ foo: "bar" }, secret);
 
-     ctx.headers.authorization = "Bearer " + token;
 
-     await koajwt({ secret: secretAsync })(ctx, () => {});
 
-     assert.equal("bar", ctx.state.user.foo);
 
-   });
 
- });
 
 
  |