You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							79 lines
						
					
					
						
							2.1 KiB
						
					
					
				
			
		
		
	
	
							79 lines
						
					
					
						
							2.1 KiB
						
					
					
				| /*global module*/
 | |
| var Buffer = require('safe-buffer').Buffer;
 | |
| var DataStream = require('./data-stream');
 | |
| var jwa = require('jwa');
 | |
| var Stream = require('stream');
 | |
| var toString = require('./tostring');
 | |
| var util = require('util');
 | |
| 
 | |
| function base64url(string, encoding) {
 | |
|   return Buffer
 | |
|     .from(string, encoding)
 | |
|     .toString('base64')
 | |
|     .replace(/=/g, '')
 | |
|     .replace(/\+/g, '-')
 | |
|     .replace(/\//g, '_');
 | |
| }
 | |
| 
 | |
| function jwsSecuredInput(header, payload, encoding) {
 | |
|   encoding = encoding || 'utf8';
 | |
|   var encodedHeader = base64url(toString(header), 'binary');
 | |
|   var encodedPayload = base64url(toString(payload), encoding);
 | |
|   return util.format('%s.%s', encodedHeader, encodedPayload);
 | |
| }
 | |
| 
 | |
| function jwsSign(opts) {
 | |
|   var header = opts.header;
 | |
|   var payload = opts.payload;
 | |
|   var secretOrKey = opts.secret || opts.privateKey;
 | |
|   var encoding = opts.encoding;
 | |
|   var algo = jwa(header.alg);
 | |
|   var securedInput = jwsSecuredInput(header, payload, encoding);
 | |
|   var signature = algo.sign(securedInput, secretOrKey);
 | |
|   return util.format('%s.%s', securedInput, signature);
 | |
| }
 | |
| 
 | |
| function SignStream(opts) {
 | |
|   var secret = opts.secret||opts.privateKey||opts.key;
 | |
|   var secretStream = new DataStream(secret);
 | |
|   this.readable = true;
 | |
|   this.header = opts.header;
 | |
|   this.encoding = opts.encoding;
 | |
|   this.secret = this.privateKey = this.key = secretStream;
 | |
|   this.payload = new DataStream(opts.payload);
 | |
|   this.secret.once('close', function () {
 | |
|     if (!this.payload.writable && this.readable)
 | |
|       this.sign();
 | |
|   }.bind(this));
 | |
| 
 | |
|   this.payload.once('close', function () {
 | |
|     if (!this.secret.writable && this.readable)
 | |
|       this.sign();
 | |
|   }.bind(this));
 | |
| }
 | |
| util.inherits(SignStream, Stream);
 | |
| 
 | |
| SignStream.prototype.sign = function sign() {
 | |
|   try {
 | |
|     var signature = jwsSign({
 | |
|       header: this.header,
 | |
|       payload: this.payload.buffer,
 | |
|       secret: this.secret.buffer,
 | |
|       encoding: this.encoding
 | |
|     });
 | |
|     this.emit('done', signature);
 | |
|     this.emit('data', signature);
 | |
|     this.emit('end');
 | |
|     this.readable = false;
 | |
|     return signature;
 | |
|   } catch (e) {
 | |
|     this.readable = false;
 | |
|     this.emit('error', e);
 | |
|     this.emit('close');
 | |
|   }
 | |
| };
 | |
| 
 | |
| SignStream.sign = jwsSign;
 | |
| 
 | |
| module.exports = SignStream;
 |