server.js 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329
  1. // Load modules
  2. var Url = require('url');
  3. var Code = require('code');
  4. var Hawk = require('../lib');
  5. var Hoek = require('hoek');
  6. var Lab = require('lab');
  7. // Declare internals
  8. var internals = {};
  9. // Test shortcuts
  10. var lab = exports.lab = Lab.script();
  11. var describe = lab.experiment;
  12. var it = lab.test;
  13. var expect = Code.expect;
  14. describe('Server', function () {
  15. var credentialsFunc = function (id, callback) {
  16. var credentials = {
  17. id: id,
  18. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  19. algorithm: (id === '1' ? 'sha1' : 'sha256'),
  20. user: 'steve'
  21. };
  22. return callback(null, credentials);
  23. };
  24. describe('authenticate()', function () {
  25. it('parses a valid authentication header (sha1)', function (done) {
  26. var req = {
  27. method: 'GET',
  28. url: '/resource/4?filter=a',
  29. host: 'example.com',
  30. port: 8080,
  31. authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'
  32. };
  33. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  34. expect(err).to.not.exist();
  35. expect(credentials.user).to.equal('steve');
  36. done();
  37. });
  38. });
  39. it('parses a valid authentication header (sha256)', function (done) {
  40. var req = {
  41. method: 'GET',
  42. url: '/resource/1?b=1&a=2',
  43. host: 'example.com',
  44. port: 8000,
  45. authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"'
  46. };
  47. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  48. expect(err).to.not.exist();
  49. expect(credentials.user).to.equal('steve');
  50. done();
  51. });
  52. });
  53. it('parses a valid authentication header (host override)', function (done) {
  54. var req = {
  55. method: 'GET',
  56. url: '/resource/4?filter=a',
  57. headers: {
  58. host: 'example1.com:8080',
  59. authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'
  60. }
  61. };
  62. Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  63. expect(err).to.not.exist();
  64. expect(credentials.user).to.equal('steve');
  65. done();
  66. });
  67. });
  68. it('parses a valid authentication header (host port override)', function (done) {
  69. var req = {
  70. method: 'GET',
  71. url: '/resource/4?filter=a',
  72. headers: {
  73. host: 'example1.com:80',
  74. authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'
  75. }
  76. };
  77. Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', port: 8080, localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  78. expect(err).to.not.exist();
  79. expect(credentials.user).to.equal('steve');
  80. done();
  81. });
  82. });
  83. it('parses a valid authentication header (POST with payload)', function (done) {
  84. var req = {
  85. method: 'POST',
  86. url: '/resource/4?filter=a',
  87. host: 'example.com',
  88. port: 8080,
  89. authorization: 'Hawk id="123456", ts="1357926341", nonce="1AwuJD", hash="qAiXIVv+yjDATneWxZP2YCTa9aHRgQdnH9b3Wc+o3dg=", ext="some-app-data", mac="UeYcj5UoTVaAWXNvJfLVia7kU3VabxCqrccXP8sUGC4="'
  90. };
  91. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1357926341000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  92. expect(err).to.not.exist();
  93. expect(credentials.user).to.equal('steve');
  94. done();
  95. });
  96. });
  97. it('errors on missing hash', function (done) {
  98. var req = {
  99. method: 'GET',
  100. url: '/resource/1?b=1&a=2',
  101. host: 'example.com',
  102. port: 8000,
  103. authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"'
  104. };
  105. Hawk.server.authenticate(req, credentialsFunc, { payload: 'body', localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  106. expect(err).to.exist();
  107. expect(err.output.payload.message).to.equal('Missing required payload hash');
  108. done();
  109. });
  110. });
  111. it('errors on a stale timestamp', function (done) {
  112. var req = {
  113. method: 'GET',
  114. url: '/resource/4?filter=a',
  115. host: 'example.com',
  116. port: 8080,
  117. authorization: 'Hawk id="123456", ts="1362337299", nonce="UzmxSs", ext="some-app-data", mac="wnNUxchvvryMH2RxckTdZ/gY3ijzvccx4keVvELC61w="'
  118. };
  119. Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
  120. expect(err).to.exist();
  121. expect(err.output.payload.message).to.equal('Stale timestamp');
  122. var header = err.output.headers['WWW-Authenticate'];
  123. var ts = header.match(/^Hawk ts\=\"(\d+)\"\, tsm\=\"([^\"]+)\"\, error=\"Stale timestamp\"$/);
  124. var now = Hawk.utils.now();
  125. expect(parseInt(ts[1], 10) * 1000).to.be.within(now - 1000, now + 1000);
  126. var res = {
  127. headers: {
  128. 'www-authenticate': header
  129. }
  130. };
  131. expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(true);
  132. done();
  133. });
  134. });
  135. it('errors on a replay', function (done) {
  136. var req = {
  137. method: 'GET',
  138. url: '/resource/4?filter=a',
  139. host: 'example.com',
  140. port: 8080,
  141. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"'
  142. };
  143. var memoryCache = {};
  144. var options = {
  145. localtimeOffsetMsec: 1353788437000 - Hawk.utils.now(),
  146. nonceFunc: function (key, nonce, ts, callback) {
  147. if (memoryCache[key + nonce]) {
  148. return callback(new Error());
  149. }
  150. memoryCache[key + nonce] = true;
  151. return callback();
  152. }
  153. };
  154. Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials1, artifacts1) {
  155. expect(err).to.not.exist();
  156. expect(credentials1.user).to.equal('steve');
  157. Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials2, artifacts2) {
  158. expect(err).to.exist();
  159. expect(err.output.payload.message).to.equal('Invalid nonce');
  160. done();
  161. });
  162. });
  163. });
  164. it('does not error on nonce collision if keys differ', function (done) {
  165. var reqSteve = {
  166. method: 'GET',
  167. url: '/resource/4?filter=a',
  168. host: 'example.com',
  169. port: 8080,
  170. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"'
  171. };
  172. var reqBob = {
  173. method: 'GET',
  174. url: '/resource/4?filter=a',
  175. host: 'example.com',
  176. port: 8080,
  177. authorization: 'Hawk id="456", ts="1353788437", nonce="k3j4h2", mac="LXfmTnRzrLd9TD7yfH+4se46Bx6AHyhpM94hLCiNia4=", ext="hello"'
  178. };
  179. var credentialsFuncion = function (id, callback) {
  180. var credentials = {
  181. '123': {
  182. id: id,
  183. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  184. algorithm: (id === '1' ? 'sha1' : 'sha256'),
  185. user: 'steve'
  186. },
  187. '456': {
  188. id: id,
  189. key: 'xrunpaw3489ruxnpa98w4rxnwerxhqb98rpaxn39848',
  190. algorithm: (id === '1' ? 'sha1' : 'sha256'),
  191. user: 'bob'
  192. }
  193. };
  194. return callback(null, credentials[id]);
  195. };
  196. var memoryCache = {};
  197. var options = {
  198. localtimeOffsetMsec: 1353788437000 - Hawk.utils.now(),
  199. nonceFunc: function (key, nonce, ts, callback) {
  200. if (memoryCache[key + nonce]) {
  201. return callback(new Error());
  202. }
  203. memoryCache[key + nonce] = true;
  204. return callback();
  205. }
  206. };
  207. Hawk.server.authenticate(reqSteve, credentialsFuncion, options, function (err, credentials1, artifacts1) {
  208. expect(err).to.not.exist();
  209. expect(credentials1.user).to.equal('steve');
  210. Hawk.server.authenticate(reqBob, credentialsFuncion, options, function (err, credentials2, artifacts2) {
  211. expect(err).to.not.exist();
  212. expect(credentials2.user).to.equal('bob');
  213. done();
  214. });
  215. });
  216. });
  217. it('errors on an invalid authentication header: wrong scheme', function (done) {
  218. var req = {
  219. method: 'GET',
  220. url: '/resource/4?filter=a',
  221. host: 'example.com',
  222. port: 8080,
  223. authorization: 'Basic asdasdasdasd'
  224. };
  225. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  226. expect(err).to.exist();
  227. expect(err.output.payload.message).to.not.exist();
  228. done();
  229. });
  230. });
  231. it('errors on an invalid authentication header: no scheme', function (done) {
  232. var req = {
  233. method: 'GET',
  234. url: '/resource/4?filter=a',
  235. host: 'example.com',
  236. port: 8080,
  237. authorization: '!@#'
  238. };
  239. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  240. expect(err).to.exist();
  241. expect(err.output.payload.message).to.equal('Invalid header syntax');
  242. done();
  243. });
  244. });
  245. it('errors on an missing authorization header', function (done) {
  246. var req = {
  247. method: 'GET',
  248. url: '/resource/4?filter=a',
  249. host: 'example.com',
  250. port: 8080
  251. };
  252. Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
  253. expect(err).to.exist();
  254. expect(err.isMissing).to.equal(true);
  255. done();
  256. });
  257. });
  258. it('errors on an missing host header', function (done) {
  259. var req = {
  260. method: 'GET',
  261. url: '/resource/4?filter=a',
  262. headers: {
  263. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  264. }
  265. };
  266. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  267. expect(err).to.exist();
  268. expect(err.output.payload.message).to.equal('Invalid Host header');
  269. done();
  270. });
  271. });
  272. it('errors on an missing authorization attribute (id)', function (done) {
  273. var req = {
  274. method: 'GET',
  275. url: '/resource/4?filter=a',
  276. host: 'example.com',
  277. port: 8080,
  278. authorization: 'Hawk ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  279. };
  280. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  281. expect(err).to.exist();
  282. expect(err.output.payload.message).to.equal('Missing attributes');
  283. done();
  284. });
  285. });
  286. it('errors on an missing authorization attribute (ts)', function (done) {
  287. var req = {
  288. method: 'GET',
  289. url: '/resource/4?filter=a',
  290. host: 'example.com',
  291. port: 8080,
  292. authorization: 'Hawk id="123", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  293. };
  294. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  295. expect(err).to.exist();
  296. expect(err.output.payload.message).to.equal('Missing attributes');
  297. done();
  298. });
  299. });
  300. it('errors on an missing authorization attribute (nonce)', function (done) {
  301. var req = {
  302. method: 'GET',
  303. url: '/resource/4?filter=a',
  304. host: 'example.com',
  305. port: 8080,
  306. authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  307. };
  308. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  309. expect(err).to.exist();
  310. expect(err.output.payload.message).to.equal('Missing attributes');
  311. done();
  312. });
  313. });
  314. it('errors on an missing authorization attribute (mac)', function (done) {
  315. var req = {
  316. method: 'GET',
  317. url: '/resource/4?filter=a',
  318. host: 'example.com',
  319. port: 8080,
  320. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", ext="hello"'
  321. };
  322. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  323. expect(err).to.exist();
  324. expect(err.output.payload.message).to.equal('Missing attributes');
  325. done();
  326. });
  327. });
  328. it('errors on an unknown authorization attribute', function (done) {
  329. var req = {
  330. method: 'GET',
  331. url: '/resource/4?filter=a',
  332. host: 'example.com',
  333. port: 8080,
  334. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", x="3", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  335. };
  336. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  337. expect(err).to.exist();
  338. expect(err.output.payload.message).to.equal('Unknown attribute: x');
  339. done();
  340. });
  341. });
  342. it('errors on an bad authorization header format', function (done) {
  343. var req = {
  344. method: 'GET',
  345. url: '/resource/4?filter=a',
  346. host: 'example.com',
  347. port: 8080,
  348. authorization: 'Hawk id="123\\", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  349. };
  350. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  351. expect(err).to.exist();
  352. expect(err.output.payload.message).to.equal('Bad header format');
  353. done();
  354. });
  355. });
  356. it('errors on an bad authorization attribute value', function (done) {
  357. var req = {
  358. method: 'GET',
  359. url: '/resource/4?filter=a',
  360. host: 'example.com',
  361. port: 8080,
  362. authorization: 'Hawk id="\t", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  363. };
  364. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  365. expect(err).to.exist();
  366. expect(err.output.payload.message).to.equal('Bad attribute value: id');
  367. done();
  368. });
  369. });
  370. it('errors on an empty authorization attribute value', function (done) {
  371. var req = {
  372. method: 'GET',
  373. url: '/resource/4?filter=a',
  374. host: 'example.com',
  375. port: 8080,
  376. authorization: 'Hawk id="", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  377. };
  378. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  379. expect(err).to.exist();
  380. expect(err.output.payload.message).to.equal('Bad attribute value: id');
  381. done();
  382. });
  383. });
  384. it('errors on duplicated authorization attribute key', function (done) {
  385. var req = {
  386. method: 'GET',
  387. url: '/resource/4?filter=a',
  388. host: 'example.com',
  389. port: 8080,
  390. authorization: 'Hawk id="123", id="456", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  391. };
  392. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  393. expect(err).to.exist();
  394. expect(err.output.payload.message).to.equal('Duplicate attribute: id');
  395. done();
  396. });
  397. });
  398. it('errors on an invalid authorization header format', function (done) {
  399. var req = {
  400. method: 'GET',
  401. url: '/resource/4?filter=a',
  402. host: 'example.com',
  403. port: 8080,
  404. authorization: 'Hawk'
  405. };
  406. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  407. expect(err).to.exist();
  408. expect(err.output.payload.message).to.equal('Invalid header syntax');
  409. done();
  410. });
  411. });
  412. it('errors on an bad host header (missing host)', function (done) {
  413. var req = {
  414. method: 'GET',
  415. url: '/resource/4?filter=a',
  416. headers: {
  417. host: ':8080',
  418. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  419. }
  420. };
  421. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  422. expect(err).to.exist();
  423. expect(err.output.payload.message).to.equal('Invalid Host header');
  424. done();
  425. });
  426. });
  427. it('errors on an bad host header (pad port)', function (done) {
  428. var req = {
  429. method: 'GET',
  430. url: '/resource/4?filter=a',
  431. headers: {
  432. host: 'example.com:something',
  433. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  434. }
  435. };
  436. Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  437. expect(err).to.exist();
  438. expect(err.output.payload.message).to.equal('Invalid Host header');
  439. done();
  440. });
  441. });
  442. it('errors on credentialsFunc error', function (done) {
  443. var req = {
  444. method: 'GET',
  445. url: '/resource/4?filter=a',
  446. host: 'example.com',
  447. port: 8080,
  448. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  449. };
  450. var credentialsFuncion = function (id, callback) {
  451. return callback(new Error('Unknown user'));
  452. };
  453. Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  454. expect(err).to.exist();
  455. expect(err.message).to.equal('Unknown user');
  456. done();
  457. });
  458. });
  459. it('errors on credentialsFunc error (with credentials)', function (done) {
  460. var req = {
  461. method: 'GET',
  462. url: '/resource/4?filter=a',
  463. host: 'example.com',
  464. port: 8080,
  465. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  466. };
  467. var credentialsFuncion = function (id, callback) {
  468. return callback(new Error('Unknown user'), { some: 'value' });
  469. };
  470. Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  471. expect(err).to.exist();
  472. expect(err.message).to.equal('Unknown user');
  473. expect(credentials.some).to.equal('value');
  474. done();
  475. });
  476. });
  477. it('errors on missing credentials', function (done) {
  478. var req = {
  479. method: 'GET',
  480. url: '/resource/4?filter=a',
  481. host: 'example.com',
  482. port: 8080,
  483. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  484. };
  485. var credentialsFuncion = function (id, callback) {
  486. return callback(null, null);
  487. };
  488. Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  489. expect(err).to.exist();
  490. expect(err.output.payload.message).to.equal('Unknown credentials');
  491. done();
  492. });
  493. });
  494. it('errors on invalid credentials (id)', function (done) {
  495. var req = {
  496. method: 'GET',
  497. url: '/resource/4?filter=a',
  498. host: 'example.com',
  499. port: 8080,
  500. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  501. };
  502. var credentialsFuncion = function (id, callback) {
  503. var credentials = {
  504. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  505. user: 'steve'
  506. };
  507. return callback(null, credentials);
  508. };
  509. Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  510. expect(err).to.exist();
  511. expect(err.message).to.equal('Invalid credentials');
  512. expect(err.output.payload.message).to.equal('An internal server error occurred');
  513. done();
  514. });
  515. });
  516. it('errors on invalid credentials (key)', function (done) {
  517. var req = {
  518. method: 'GET',
  519. url: '/resource/4?filter=a',
  520. host: 'example.com',
  521. port: 8080,
  522. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  523. };
  524. var credentialsFuncion = function (id, callback) {
  525. var credentials = {
  526. id: '23434d3q4d5345d',
  527. user: 'steve'
  528. };
  529. return callback(null, credentials);
  530. };
  531. Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  532. expect(err).to.exist();
  533. expect(err.message).to.equal('Invalid credentials');
  534. expect(err.output.payload.message).to.equal('An internal server error occurred');
  535. done();
  536. });
  537. });
  538. it('errors on unknown credentials algorithm', function (done) {
  539. var req = {
  540. method: 'GET',
  541. url: '/resource/4?filter=a',
  542. host: 'example.com',
  543. port: 8080,
  544. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  545. };
  546. var credentialsFuncion = function (id, callback) {
  547. var credentials = {
  548. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  549. algorithm: 'hmac-sha-0',
  550. user: 'steve'
  551. };
  552. return callback(null, credentials);
  553. };
  554. Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  555. expect(err).to.exist();
  556. expect(err.message).to.equal('Unknown algorithm');
  557. expect(err.output.payload.message).to.equal('An internal server error occurred');
  558. done();
  559. });
  560. });
  561. it('errors on unknown bad mac', function (done) {
  562. var req = {
  563. method: 'GET',
  564. url: '/resource/4?filter=a',
  565. host: 'example.com',
  566. port: 8080,
  567. authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcU4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
  568. };
  569. var credentialsFuncion = function (id, callback) {
  570. var credentials = {
  571. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  572. algorithm: 'sha256',
  573. user: 'steve'
  574. };
  575. return callback(null, credentials);
  576. };
  577. Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
  578. expect(err).to.exist();
  579. expect(err.output.payload.message).to.equal('Bad mac');
  580. done();
  581. });
  582. });
  583. });
  584. describe('header()', function () {
  585. it('generates header', function (done) {
  586. var credentials = {
  587. id: '123456',
  588. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  589. algorithm: 'sha256',
  590. user: 'steve'
  591. };
  592. var artifacts = {
  593. method: 'POST',
  594. host: 'example.com',
  595. port: '8080',
  596. resource: '/resource/4?filter=a',
  597. ts: '1398546787',
  598. nonce: 'xUwusx',
  599. hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
  600. ext: 'some-app-data',
  601. mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
  602. id: '123456'
  603. };
  604. var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
  605. expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"');
  606. done();
  607. });
  608. it('generates header (empty payload)', function (done) {
  609. var credentials = {
  610. id: '123456',
  611. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  612. algorithm: 'sha256',
  613. user: 'steve'
  614. };
  615. var artifacts = {
  616. method: 'POST',
  617. host: 'example.com',
  618. port: '8080',
  619. resource: '/resource/4?filter=a',
  620. ts: '1398546787',
  621. nonce: 'xUwusx',
  622. hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
  623. ext: 'some-app-data',
  624. mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
  625. id: '123456'
  626. };
  627. var header = Hawk.server.header(credentials, artifacts, { payload: '', contentType: 'text/plain', ext: 'response-specific' });
  628. expect(header).to.equal('Hawk mac=\"i8/kUBDx0QF+PpCtW860kkV/fa9dbwEoe/FpGUXowf0=\", hash=\"q/t+NNAkQZNlq/aAD6PlexImwQTxwgT2MahfTa9XRLA=\", ext=\"response-specific\"');
  629. done();
  630. });
  631. it('generates header (pre calculated hash)', function (done) {
  632. var credentials = {
  633. id: '123456',
  634. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  635. algorithm: 'sha256',
  636. user: 'steve'
  637. };
  638. var artifacts = {
  639. method: 'POST',
  640. host: 'example.com',
  641. port: '8080',
  642. resource: '/resource/4?filter=a',
  643. ts: '1398546787',
  644. nonce: 'xUwusx',
  645. hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
  646. ext: 'some-app-data',
  647. mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
  648. id: '123456'
  649. };
  650. var options = { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' };
  651. options.hash = Hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
  652. var header = Hawk.server.header(credentials, artifacts, options);
  653. expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"');
  654. done();
  655. });
  656. it('generates header (null ext)', function (done) {
  657. var credentials = {
  658. id: '123456',
  659. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  660. algorithm: 'sha256',
  661. user: 'steve'
  662. };
  663. var artifacts = {
  664. method: 'POST',
  665. host: 'example.com',
  666. port: '8080',
  667. resource: '/resource/4?filter=a',
  668. ts: '1398546787',
  669. nonce: 'xUwusx',
  670. hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
  671. mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
  672. id: '123456'
  673. };
  674. var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: null });
  675. expect(header).to.equal('Hawk mac=\"6PrybJTJs20jsgBw5eilXpcytD8kUbaIKNYXL+6g0ns=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\"');
  676. done();
  677. });
  678. it('errors on missing artifacts', function (done) {
  679. var credentials = {
  680. id: '123456',
  681. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  682. algorithm: 'sha256',
  683. user: 'steve'
  684. };
  685. var header = Hawk.server.header(credentials, null, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
  686. expect(header).to.equal('');
  687. done();
  688. });
  689. it('errors on invalid artifacts', function (done) {
  690. var credentials = {
  691. id: '123456',
  692. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  693. algorithm: 'sha256',
  694. user: 'steve'
  695. };
  696. var header = Hawk.server.header(credentials, 5, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
  697. expect(header).to.equal('');
  698. done();
  699. });
  700. it('errors on missing credentials', function (done) {
  701. var artifacts = {
  702. method: 'POST',
  703. host: 'example.com',
  704. port: '8080',
  705. resource: '/resource/4?filter=a',
  706. ts: '1398546787',
  707. nonce: 'xUwusx',
  708. hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
  709. ext: 'some-app-data',
  710. mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
  711. id: '123456'
  712. };
  713. var header = Hawk.server.header(null, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
  714. expect(header).to.equal('');
  715. done();
  716. });
  717. it('errors on invalid credentials (key)', function (done) {
  718. var credentials = {
  719. id: '123456',
  720. algorithm: 'sha256',
  721. user: 'steve'
  722. };
  723. var artifacts = {
  724. method: 'POST',
  725. host: 'example.com',
  726. port: '8080',
  727. resource: '/resource/4?filter=a',
  728. ts: '1398546787',
  729. nonce: 'xUwusx',
  730. hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
  731. ext: 'some-app-data',
  732. mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
  733. id: '123456'
  734. };
  735. var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
  736. expect(header).to.equal('');
  737. done();
  738. });
  739. it('errors on invalid algorithm', function (done) {
  740. var credentials = {
  741. id: '123456',
  742. key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  743. algorithm: 'x',
  744. user: 'steve'
  745. };
  746. var artifacts = {
  747. method: 'POST',
  748. host: 'example.com',
  749. port: '8080',
  750. resource: '/resource/4?filter=a',
  751. ts: '1398546787',
  752. nonce: 'xUwusx',
  753. hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
  754. ext: 'some-app-data',
  755. mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
  756. id: '123456'
  757. };
  758. var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
  759. expect(header).to.equal('');
  760. done();
  761. });
  762. });
  763. describe('authenticateBewit()', function () {
  764. it('errors on uri too long', function (done) {
  765. var long = '/';
  766. for (var i = 0; i < 5000; ++i) {
  767. long += 'x';
  768. }
  769. var req = {
  770. method: 'GET',
  771. url: long,
  772. host: 'example.com',
  773. port: 8080,
  774. authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'
  775. };
  776. Hawk.server.authenticateBewit(req, credentialsFunc, {}, function (err, credentials, bewit) {
  777. expect(err).to.exist();
  778. expect(err.output.statusCode).to.equal(400);
  779. expect(err.message).to.equal('Resource path exceeds max length');
  780. done();
  781. });
  782. });
  783. });
  784. describe('authenticateMessage()', function () {
  785. it('errors on invalid authorization (ts)', function (done) {
  786. credentialsFunc('123456', function (err, credentials1) {
  787. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  788. delete auth.ts;
  789. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
  790. expect(err).to.exist();
  791. expect(err.message).to.equal('Invalid authorization');
  792. done();
  793. });
  794. });
  795. });
  796. it('errors on invalid authorization (nonce)', function (done) {
  797. credentialsFunc('123456', function (err, credentials1) {
  798. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  799. delete auth.nonce;
  800. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
  801. expect(err).to.exist();
  802. expect(err.message).to.equal('Invalid authorization');
  803. done();
  804. });
  805. });
  806. });
  807. it('errors on invalid authorization (hash)', function (done) {
  808. credentialsFunc('123456', function (err, credentials1) {
  809. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  810. delete auth.hash;
  811. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
  812. expect(err).to.exist();
  813. expect(err.message).to.equal('Invalid authorization');
  814. done();
  815. });
  816. });
  817. });
  818. it('errors with credentials', function (done) {
  819. credentialsFunc('123456', function (err, credentials1) {
  820. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  821. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, function (id, callback) {
  822. callback(new Error('something'), { some: 'value' });
  823. }, {}, function (err, credentials2) {
  824. expect(err).to.exist();
  825. expect(err.message).to.equal('something');
  826. expect(credentials2.some).to.equal('value');
  827. done();
  828. });
  829. });
  830. });
  831. it('errors on nonce collision', function (done) {
  832. credentialsFunc('123456', function (err, credentials1) {
  833. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  834. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {
  835. nonceFunc: function (key, nonce, ts, nonceCallback) {
  836. nonceCallback(true);
  837. }
  838. }, function (err, credentials2) {
  839. expect(err).to.exist();
  840. expect(err.message).to.equal('Invalid nonce');
  841. done();
  842. });
  843. });
  844. });
  845. it('should generate an authorization then successfully parse it', function (done) {
  846. credentialsFunc('123456', function (err, credentials1) {
  847. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  848. expect(auth).to.exist();
  849. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
  850. expect(err).to.not.exist();
  851. expect(credentials2.user).to.equal('steve');
  852. done();
  853. });
  854. });
  855. });
  856. it('should fail authorization on mismatching host', function (done) {
  857. credentialsFunc('123456', function (err, credentials1) {
  858. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  859. expect(auth).to.exist();
  860. Hawk.server.authenticateMessage('example1.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
  861. expect(err).to.exist();
  862. expect(err.message).to.equal('Bad mac');
  863. done();
  864. });
  865. });
  866. });
  867. it('should fail authorization on stale timestamp', function (done) {
  868. credentialsFunc('123456', function (err, credentials1) {
  869. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  870. expect(auth).to.exist();
  871. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { localtimeOffsetMsec: 100000 }, function (err, credentials2) {
  872. expect(err).to.exist();
  873. expect(err.message).to.equal('Stale timestamp');
  874. done();
  875. });
  876. });
  877. });
  878. it('overrides timestampSkewSec', function (done) {
  879. credentialsFunc('123456', function (err, credentials1) {
  880. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1, localtimeOffsetMsec: 100000 });
  881. expect(auth).to.exist();
  882. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { timestampSkewSec: 500 }, function (err, credentials2) {
  883. expect(err).to.not.exist();
  884. done();
  885. });
  886. });
  887. });
  888. it('should fail authorization on invalid authorization', function (done) {
  889. credentialsFunc('123456', function (err, credentials1) {
  890. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  891. expect(auth).to.exist();
  892. delete auth.id;
  893. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
  894. expect(err).to.exist();
  895. expect(err.message).to.equal('Invalid authorization');
  896. done();
  897. });
  898. });
  899. });
  900. it('should fail authorization on bad hash', function (done) {
  901. credentialsFunc('123456', function (err, credentials1) {
  902. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  903. expect(auth).to.exist();
  904. Hawk.server.authenticateMessage('example.com', 8080, 'some message1', auth, credentialsFunc, {}, function (err, credentials2) {
  905. expect(err).to.exist();
  906. expect(err.message).to.equal('Bad message hash');
  907. done();
  908. });
  909. });
  910. });
  911. it('should fail authorization on nonce error', function (done) {
  912. credentialsFunc('123456', function (err, credentials1) {
  913. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  914. expect(auth).to.exist();
  915. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {
  916. nonceFunc: function (key, nonce, ts, callback) {
  917. callback(new Error('kaboom'));
  918. }
  919. }, function (err, credentials2) {
  920. expect(err).to.exist();
  921. expect(err.message).to.equal('Invalid nonce');
  922. done();
  923. });
  924. });
  925. });
  926. it('should fail authorization on credentials error', function (done) {
  927. credentialsFunc('123456', function (err, credentials1) {
  928. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  929. expect(auth).to.exist();
  930. var errFunc = function (id, callback) {
  931. callback(new Error('kablooey'));
  932. };
  933. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {
  934. expect(err).to.exist();
  935. expect(err.message).to.equal('kablooey');
  936. done();
  937. });
  938. });
  939. });
  940. it('should fail authorization on missing credentials', function (done) {
  941. credentialsFunc('123456', function (err, credentials1) {
  942. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  943. expect(auth).to.exist();
  944. var errFunc = function (id, callback) {
  945. callback();
  946. };
  947. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {
  948. expect(err).to.exist();
  949. expect(err.message).to.equal('Unknown credentials');
  950. done();
  951. });
  952. });
  953. });
  954. it('should fail authorization on invalid credentials', function (done) {
  955. credentialsFunc('123456', function (err, credentials1) {
  956. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  957. expect(auth).to.exist();
  958. var errFunc = function (id, callback) {
  959. callback(null, {});
  960. };
  961. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {
  962. expect(err).to.exist();
  963. expect(err.message).to.equal('Invalid credentials');
  964. done();
  965. });
  966. });
  967. });
  968. it('should fail authorization on invalid credentials algorithm', function (done) {
  969. credentialsFunc('123456', function (err, credentials1) {
  970. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
  971. expect(auth).to.exist();
  972. var errFunc = function (id, callback) {
  973. callback(null, { key: '123', algorithm: '456' });
  974. };
  975. Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {
  976. expect(err).to.exist();
  977. expect(err.message).to.equal('Unknown algorithm');
  978. done();
  979. });
  980. });
  981. });
  982. it('should fail on missing host', function (done) {
  983. credentialsFunc('123456', function (err, credentials) {
  984. var auth = Hawk.client.message(null, 8080, 'some message', { credentials: credentials });
  985. expect(auth).to.not.exist();
  986. done();
  987. });
  988. });
  989. it('should fail on missing credentials', function (done) {
  990. var auth = Hawk.client.message('example.com', 8080, 'some message', {});
  991. expect(auth).to.not.exist();
  992. done();
  993. });
  994. it('should fail on invalid algorithm', function (done) {
  995. credentialsFunc('123456', function (err, credentials) {
  996. var creds = Hoek.clone(credentials);
  997. creds.algorithm = 'blah';
  998. var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: creds });
  999. expect(auth).to.not.exist();
  1000. done();
  1001. });
  1002. });
  1003. });
  1004. describe('authenticatePayloadHash()', function () {
  1005. it('checks payload hash', function (done) {
  1006. expect(Hawk.server.authenticatePayloadHash('abcdefg', { hash: 'abcdefg' })).to.equal(true);
  1007. expect(Hawk.server.authenticatePayloadHash('1234567', { hash: 'abcdefg' })).to.equal(false);
  1008. done();
  1009. });
  1010. });
  1011. });