UNPKG

2.32 kBJavaScriptView Raw
1'use strict';
2
3/**
4 * Authorization Token
5 * @module auth_token
6 */
7
8var crypto = require('crypto');
9var config = require('./config');
10
11function digest(message, key) {
12 return crypto.createHmac("sha256", new Buffer(key, "hex")).update(message).digest('hex');
13}
14
15/**
16 * Escape url using lowercase hex code
17 * @param {string} url a url string
18 * @return {string} escaped url
19 */
20function escapeToLower(url) {
21 return encodeURIComponent(url).replace(/%../g, function (match) {
22 return match.toLowerCase();
23 });
24}
25
26/**
27 * Auth token options
28 * @typedef {object} authTokenOptions
29 * @property {string} [token_name="__cld_token__"] The name of the token.
30 * @property {string} key The secret key required to sign the token.
31 * @property {string} ip The IP address of the client.
32 * @property {number} start_time=now The start time of the token in seconds from epoch.
33 * @property {string} expiration The expiration time of the token in seconds from epoch.
34 * @property {string} duration The duration of the token (from start_time).
35 * @property {string} acl The ACL for the token.
36 * @property {string} url The URL to authentication in case of a URL token.
37 *
38 */
39
40/**
41 * Generate an authorization token
42 * @param {authTokenOptions} options
43 * @returns {string} the authorization token
44 */
45module.exports = function (options) {
46 var tokenName = options.token_name ? options.token_name : "__cld_token__";
47 if (options.expiration == null) {
48 if (options.duration != null) {
49 var start = options.start_time != null ? options.start_time : Math.round(Date.now() / 1000);
50 options.expiration = start + options.duration;
51 } else {
52 throw new Error("Must provide either expiration or duration");
53 }
54 }
55 var tokenParts = [];
56 if (options.ip != null) {
57 tokenParts.push(`ip=${options.ip}`);
58 }
59 if (options.start_time != null) {
60 tokenParts.push(`st=${options.start_time}`);
61 }
62 tokenParts.push(`exp=${options.expiration}`);
63 if (options.acl != null) {
64 tokenParts.push(`acl=${escapeToLower(options.acl)}`);
65 }
66 var toSign = [].concat(tokenParts);
67 if (options.url) {
68 var url = escapeToLower(options.url);
69 toSign.push(`url=${url}`);
70 }
71 var auth = digest(toSign.join("~"), options.key);
72 tokenParts.push(`hmac=${auth}`);
73 return `${tokenName}=${tokenParts.join('~')}`;
74};
\No newline at end of file