Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

w3gram

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

w3gram - npm Package Compare versions

Comparing version
0.1.0
to
0.1.1
+9
.travis.yml
language: node_js
node_js:
- "0.10"
- "0.11"
addons:
postgresql: "9.3"
before_script:
- psql -c 'create database w3gram_test;' -U postgres
env: DATABASE_URL=postgresql://postgres@localhost/w3gram_test
PingPong = W3gram._.PingPong
describe 'W3gram._.PingPong', ->
beforeEach ->
@pingPong = new PingPong(
silenceTimeoutMs: 10, pingSlackMs: 20, rttMs: 20)
describe 'when pings are returned immediately', ->
beforeEach ->
@pingCount = 0
@pingPong.onPing = (data) =>
@pingCount += 1
setImmediate =>
@pingPong.receivedPong data
it 'issues 8-10 ping requests in 100ms', (done) ->
@pingPong.onPingTimeout = ->
expect('Should not timeout').to.equal false
done()
onTimeout = =>
@pingPong.disconnected()
expect(@pingCount).to.be.at.least 8
expect(@pingCount).to.be.at.most 10
done()
@pingPong.startedConnecting()
setTimeout onTimeout, 100
null
describe 'when pings are not returned', ->
beforeEach ->
@pingCount = 0
@pingPong.onPing = (data) =>
@pingCount += 1
it 'issues 1 ping and disconnects ', (done) ->
@pingPong.onPingTimeout = =>
expect(@pingCount).to.equal 1
done()
@pingPong.startedConnecting()
null
WsClient = W3gram._.WsClient
describe 'W3gram._.WsClient', ->
beforeEach ->
@sandbox = sinon.sandbox.create()
W3gram._.jsonRequest('POST', "#{testXhrServer}/reset")
.then (json) =>
@serverUrl = json.url
@serverMak = json.mak
appOptions = name: 'App#register Test', origin: '*'
@server = new W3gram._.Server @serverUrl
@server.createApp @serverMak, appOptions
.then (app) =>
@app = app
@deviceId = 'tablet-device-id'
@app.token @deviceId
.then (token) =>
@token = token
@app.secret = null
@app.register @deviceId, @token
.then (registration) =>
@registration = registration
@registration.route()
.then (wsUrl) =>
@wsUrl = wsUrl
afterEach ->
@sandbox.restore()
describe 'with hyper-ping settings', ->
beforeEach ->
@wsClient = new WsClient @wsUrl,
silenceTimeoutMs: 10, pingSlackMs: 20, rttMs: 20
it 'sends 8-10 pings in 100ms', (done) ->
@wsClient.connected.then =>
pingSpy = @sandbox.spy @wsClient, 'sendPing'
closeSpy = @sandbox.spy @wsClient, 'close'
onTimeout = =>
expect(closeSpy.callCount).to.equal 0
expect(pingSpy.callCount).to.be.at.least 8
expect(pingSpy.callCount).to.be.at.most 10
done()
setTimeout onTimeout, 100
null
+8
-4

@@ -449,3 +449,3 @@ // Generated by CoffeeScript 1.8.0

options || (options = {});
this._silenceTimeout = options.pingTimeoutMs || 5000;
this._silenceTimeout = options.silenceTimeoutMs || 5000;
this._roundTrip = options.rttMs || 20000;

@@ -469,3 +469,3 @@ this._pingSlack = options.pingSlackMs || 5000;

if (data.nonce === this._pongNonce) {
roundTrip = Date.now() - message.ts;
roundTrip = Date.now() - data.ts;
this._roundTrip = this._roundTrip * 0.2 + roundTrip * 0.8;

@@ -502,3 +502,2 @@ }

this._silenceTimer = null;
return;
if (this._pingTimer !== null) {

@@ -788,3 +787,7 @@ return;

this._pingPong = new W3gram._.PingPong(options);
this._pingPong.onPing = this.sendPing.bind(this);
this._pingPong.onPing = (function(_this) {
return function(data) {
return _this.sendPing(data);
};
})(this);
this._pingPong.onPingTimeout = (function(_this) {

@@ -797,2 +800,3 @@ return function() {

this._resolveConnected = null;
this.connected = null;
this.closed = new W3gram._.Promise((function(_this) {

@@ -799,0 +803,0 @@ return function(resolve) {

@@ -1,2 +0,2 @@

(function(){var e,t,n,i,r,o;if(e=function(){function e(){}return e.prototype.setupPushManager=function(e){return this.pushRegistrationManager=new t.PushRegistrationManager(e)},e.prototype.pushRegistrationManager=null,e}(),t=new e,t.ServiceWorkerRegistration=e,t._={},"undefined"!=typeof global&&"undefined"!=typeof module&&"exports"in module)r=global,o=module.require.bind(module),module.exports=t;else if("undefined"!=typeof window&&"undefined"!=typeof navigator)r=window,o=null,window.W3gram=t;else{if("undefined"==typeof self||"undefined"==typeof navigator)throw new Error("w3gram.js loaded in an unsupported JavaScript environment.");n=self,i=self.importScripts.bind(self),self.W3gram=t}t._.global=r,t._.require=o,t._.App=function(){function e(e){var t;if(!(this.apiKey=e.key))throw new Error("The key option must be a W3gram API key");if(this.secret=e.secret||null,this.name=e.name||null,this.origin=e.origin||null,!(t=e.server))throw new Error("The server option must be a W3gram server URL");"/"===t.substring(t.length-1)&&(t=t.substring(0,t.length-1)),this.serverUrl=t,this._registerUrl=""+t+"/register"}return e.prototype.toJSON=function(){return{name:this.name,origin:this.origin,key:this.apiKey,secret:this.secret,server:this.serverUrl}},e.prototype.register=function(e,n){var i;return i={app:this.apiKey,device:e,token:n},t._.jsonRequest("POST",this._registerUrl,i).then(function(i){return function(r){return r.server=i.serverUrl,r.app=i.apiKey,r.device=e,r.token=n,new t._.DeviceRegistration(r)}}(this))},e.prototype.token=function(e){return t._.App.checkDeviceId(e).then(function(n){return function(){return n.checkCanCreateTokens().then(function(){return t._.hmac(n.secret,"device-id|"+e)})}}(this))},e.checkDeviceId=function(e){return t._.App.isValidDeviceId(e)?t._.Promise.resolve(!0):t._.Promise.reject(new t._.DOMException(t._.DOMException.SyntaxError,"Invalid device ID"))},e.isValidDeviceId=function(e){return e.length<=64?/^[A-Za-z0-9_\-]+$/.test(e):!1},e.prototype.checkCanCreateTokens=function(){return this.secret?t._.Promise.resolve(!0):t._.Promise.reject(new t._.DOMException(t._.DOMException.InvalidStateError,"Cannot generate tokens without the app secret"))},e}(),t._.DeviceRegistration=function(){function e(e){var t;this.pushUrl=e.push,this.receiverId=e.receiver,this.apiKey=e.app,this.deviceId=e.device,this.token=e.token,t=e.server,"/"===t.substring(t.length-1)&&(t=t.substring(0,t.length-1)),this.serverUrl=t,this._routeUrl=""+t+"/route"}return e.prototype.push=function(e){var n;return n={receiver:this.receiverId,message:e},t._.jsonRequest("POST",this.pushUrl,n).then(function(){return!0})},e.prototype.route=function(){var e;return e={app:this.apiKey,device:this.deviceId,receiver:this.receiverId,token:this.token},t._.jsonRequest("POST",this._routeUrl,e).then(function(e){return e.listen})},e.prototype.toJSON=function(){return{push:this.pushUrl,receiver:this.receiverId,server:this.serverUrl,app:this.apiKey,device:this.deviceId,token:this.token}},e}(),t._.DOMException=function(){function e(e,t){this.name=e,this.message=t}return e.name=null,e.NotFoundError="NotFoundError",e.InvalidStateError="InvalidStateError",e.SyntaxError="SyntaxError",e.NotFoundError="NotFoundError",e.SecurityError="SecurityError",e.NetworkError="NetworkError",e.AbortError="AbortError",e.ABORT_ERR=20,e}(),function(){var e,n,i,r,o,s,c,u,h;if(t._.hmac=function(n,r){return new t._.Promise(function(t){return t(e(i(u(n),u(r),n.length,r.length)))})},t._.require)try{n=t._.require("crypto"),n.createHmac&&(t._.hmac=function(e,i){return new t._.Promise(function(t){return t(n.createHmac("sha256",e).update(i).digest("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/\=/g,""))})})}catch(a){r=a}return i=function(e,t,n,i){var r,s,c,u;return e.length>16&&(e=o(e,n)),c=function(){var t,n;for(n=[],s=t=0;16>t;s=++t)n.push(909522486^e[s]);return n}(),u=function(){var t,n;for(n=[],s=t=0;16>t;s=++t)n.push(1549556828^e[s]);return n}(),r=o(c.concat(t),64+i),o(u.concat(r),96)},o=function(e,t){var n,i,r,o,u,h,a,l,p,_,f,d,g,v,m,w,y,P,k,T,E,S,b,N,C,M,R,O,x,I,D,U;for(e[t>>2]|=1<<31-((3&t)<<3),e[(t+8>>6<<4)+15]=t<<3,x=Array(80),n=s[0],r=s[1],u=s[2],l=s[3],_=s[4],d=s[5],v=s[6],T=s[7],S=0,N=e.length;N>S;){for(i=n,o=r,h=u,p=l,f=_,g=d,m=v,E=T,b=U=0;64>U;b=++U)16>b?O=x[b]=0|e[S+b<<2>>2]:(y=0|x[b-15<<2>>2],w=(y<<25|y>>>7)^(y<<14|y>>>18)^y>>>3,k=0|x[b-2<<2>>2],P=(k<<15|k>>>17)^(k<<13|k>>>19)^k>>>10,O=x[b]=(w+(0|x[b-7<<2>>2])|0)+(P+(0|x[b-16<<2>>2])|0)|0),a=_&d^~_&v,C=n&r^n&u^r&u,M=(n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22),R=(_<<26|_>>>6)^(_<<21|_>>>11)^(_<<7|_>>>25),I=((T+R|0)+(a+O|0)|0)+(0|c[b<<2>>2])|0,D=M+C|0,T=v,v=d,d=_,_=l+I|0,l=u,u=r,r=n,n=I+D|0;n=i+n|0,r=o+r|0,u=h+u|0,l=p+l|0,_=f+_|0,d=g+d|0,v=m+v|0,T=E+T|0,S+=16}return[n,r,u,l,_,d,v,T]},s=[],c=[],function(){var e,t,n,i,r,o,u;for(t=function(e){return 4294967296*(e-Math.floor(e))|0},r=2,u=[],n=o=0;64>o;n=++o){for(;;){for(i=!0,e=2;r>=e*e;){if(r%e===0){i=!1;break}e+=1}if(i)break;r+=1}8>n&&(s[n]=t(Math.pow(r,.5))),c[n]=t(Math.pow(r,1/3)),u.push(r+=1)}return u}(),e=function(e){var t,n,i,r,o;for(r="",t=0,i=4*e.length;i>t;)n=t,o=(e[n>>2]>>(3-(3&n)<<3)&255)<<16,n+=1,o|=(e[n>>2]>>(3-(3&n)<<3)&255)<<8,n+=1,o|=e[n>>2]>>(3-(3&n)<<3)&255,r+=h[o>>18&63],r+=h[o>>12&63],t+=1,i>t&&(r+=h[o>>6&63]),t+=1,i>t&&(r+=h[63&o]),t+=1;return r},h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",u=function(e){var t,n,i,r;for(t=[],n=i=0,r=e.length;r>=0?r>i:i>r;n=r>=0?++i:--i)t[n>>2]|=(255&e.charCodeAt(n))<<(3-(3&n)<<3);return t}}(),t._.jsonRequest=function(e,n,i){return new t._.Promise(function(r,o){var s;s=new t._.XMLHttpRequest,s.open(e,n,!0),s.onreadystatechange=function(){var e,n,i,c,u,h,a,l;if(4!==s.readyState)return!0;if(e=s.getResponseHeader("Content-Type"),e&&(a=e.indexOf(";"),-1!==a&&(e=e.substring(0,a))),u=null,h=null,"application/json"===e)try{u=JSON.parse(s.responseText||s.response)}catch(p){h=p}return l=s.status,l>=200&&300>l?h?void o(h):void r(u||{}):(0===l?(c=t._.DOMException.NetworkError,i="Could not reach Push Notification Server"):(c=t._.DOMException.SecurityError,i=u&&u.error?"Push Notification Server error: "+u.error:"Push Notification Server error: HTTP "+l),n=new t._.DOMException(c,i),0!==l&&(n.httpCode=l),void o(n))},i?(s.setRequestHeader("Content-Type","application/json; charset=utf-8"),s.send(JSON.stringify(i))):s.send()})},t._.PingPong=function(){function e(e){e||(e={}),this._silenceTimeout=e.pingTimeoutMs||5e3,this._roundTrip=e.rttMs||2e4,this._pingSlack=e.pingSlackMs||5e3,this._nextPongNonce=0,this._pongNonce=null,this._silenceTimer=null,this._pingTimer=null,this._silenceTimerHandler=this._onSilenceTimeout.bind(this),this._pingTimerHandler=this._onPingTimeout.bind(this)}return e.prototype.startedConnecting=function(){this._resetSilenceTimer()},e.prototype.receivedPong=function(e){var t;e.nonce===this._pongNonce&&(t=Date.now()-message.ts,this._roundTrip=.2*this._roundTrip+.8*t),this._resetSilenceTimer()},e.prototype.receivedMessage=function(){this._resetSilenceTimer()},e.prototype.disconnected=function(){this._disableTimers()},e.prototype.onPing=function(){throw new Error("onPing not assigned")},e.prototype.onPingTimeout=function(){throw new Error("onPingTimeout not assigned")},e.prototype._resetSilenceTimer=function(){this._disableTimers(),this._silenceTimer=setTimeout(this._silenceTimerHandler,this._silenceTimeout)},e.prototype._onSilenceTimeout=function(){null!==this._silenceTimer&&(this._silenceTimer=null)},e.prototype._sendPing=function(){this._pongNonce=this._nextPongNonce,this._nextPongNonce=this._nextPongNouce+1|0,this.onPing({nonce:this._pongNonce,ts:Date.now()}),this._pingTimer=setTimeout(this._pingTimerHandler,this._roundTrip+this._pingSlack)},e.prototype._onPingTimeout=function(){null!==this._pingTimer&&(this._pingTimer=null,this._pongNonce=null,this._disableTimers(),this.onPingTimeout())},e.prototype._disableTimers=function(){null!==this._pingTimer&&(clearTimeout(this._pingTimer),this._pingTimer=null,this._pongNonce=null),null!==this._silenceTimer&&(clearTimeout(this._silenceTimer),this._silenceTimer=null)},e}(),t._.Promise="undefined"==typeof Promise?o("es6-promise-polyfill").Promise:Promise,t._.WebSocket="undefined"==typeof WebSocket?o("ws"):WebSocket,t._.XMLHttpRequest="undefined"==typeof XMLHttpRequest?o("xhr2"):XMLHttpRequest,t.PushEvent=function(){function e(e,t){this.name="PushEvent",this.target=e,this.data=t}return e}(),t._.createPushEvent=function(e,n){return new t.PushEvent(e,n)},t.PushRegistration=function(){function e(e){if(this._deviceRegistration=e,!(this._deviceRegistration instanceof t._.DeviceRegistration))throw new Error("Illegal constructor");this.registrationId=e.receiverId,this.endpoint=e.pushUrl,this._wsClient=null,this._canceled=!1,this._initialBackoff=1e3,this._nextBackoff=null,this._resolveConnected=null,this._connected=new t._.Promise(function(e){return function(t){return e._resolveConnected=t}}(this)),this._connect()}return e.prototype.registrationId=null,e.prototype.endpoint=null,e.prototype.onpush=null,e.prototype.onpushregistrationlost=null,e.prototype._cancel=function(){this._canceled=!0,this._wsClient&&this._wsClient.close(1e3,"Receiver unregistered")},e.prototype._connect=function(){return this._wsClient&&new t._.Promise.resolve(!0),this._canceled&&new t._.Promise.reject(new Error("Unregistered")),this._nextBackoff=this._initialBackoff,this._connectOnce()},e.prototype._connectOnce=function(){this._deviceRegistration.route().then(function(e){return function(n){return e._wsClient=new t._.WsClient(n),e._wsClient.onNotification=e._onNotification.bind(e),e._wsClient.closed.then(e._onWsClosed.bind(e)),e._wsClient.connected}}(this)).then(function(e){return function(){return e._nextBackoff=e._initialBackoff,e._resolveConnected(!0),!0}}(this))["catch"](function(e){return function(){var n;e._wsClient.close(4e3,"Network error"),n=e._nextBackoff,e._nextBackoff*=2,new t._.Promise(function(t){var i;return i=function(){return t(e._connect())},setTimeout(i,n)})}}(this))},e.prototype._onNotification=function(e){this._canceled||this.onpush&&this.onpush(t._.createPushEvent(this,JSON.stringify(e)))},e.prototype._onWsClosed=function(){this._wsClient=null,this._connect()},e}(),t.PushRegistrationManager=function(){function e(e){if(!e.server)throw new Error("The server option must be a W3gram server URL");if(!e.key)throw new Error("The key option must be a W3gram API key");if(!(this._deviceId=e.device))throw new Error("The device option must be a device ID");if(!(this._token=e.token))throw new Error("The token option must be the device ID's token");this._registration=null,this._app=new t._.App({server:e.server,key:e.key})}return e.prototype.register=function(){return null!==this._registration?t._.Promise.resolve(this._registration):this._app.register(this._deviceId,this._token).then(function(e){return function(n){return e._registration||(e._registration=new t.PushRegistration(n)),e._registration._connected.then(function(){return e._registration})}}(this))},e.prototype.unregister=function(){var e,n;return this._registration?(n=this._registration,this._registration=null,n._cancel(),void t._.Promise.resolve(n)):(e=new t._.DOMException(t._.DOMException.NotFoundError,"No compatible W3gram registration found on this device"),t._.Promise.reject(e))},e.prototype.getRegistration=function(){var e;return this._registration?void t._.Promise.resolve(this._registration):(e=new t._.DOMException(t._.DOMException.NotFoundError,"No compatible W3gram registration found on this device"),t._.Promise.reject(e))},e.prototype.hasPermission=function(){return t._.Promise.resolve("granted")},e}(),t._.Server=function(){function e(e){"/"===e.substring(e.length-1)&&(e=e.substring(0,e.length-1)),this.serverUrl=e,this._makUrl=""+e+"/mak",this._appsUrl=""+e+"/apps"}return e.prototype.getMak=function(){return t._.jsonRequest("GET",""+this.serverUrl+"/mak").then(function(e){return e.mak})},e.prototype.createApp=function(e,n){var i;return i={name:n.name,origin:n.origin||"*"},t._.jsonRequest("POST",this._appsUrl,{mak:e,app:i}).then(function(e){return function(n){return n.server=e.serverUrl,new t._.App(n)}}(this))},e}(),t._.WsClient=function(){function e(e,n){this._wsUrl=e,this._ws=null,this._pingPong=new t._.PingPong(n),this._pingPong.onPing=this.sendPing.bind(this),this._pingPong.onPingTimeout=function(e){return function(){return e.close(4e3,"Ping timeout")}}(this),this._resolveClosed=null,this._resolveConnected=null,this.closed=new t._.Promise(function(e){return function(n){e._resolveClosed=n,e.connected=new t._.Promise(function(t){e._resolveConnected=t,e._connect()})}}(this))}return e.prototype.close=function(e,t){null!==this._ws&&(this._ws.onclose=null,this._ws.onerror=null,this._ws.onmessage=null,this._ws.onopen=null,e||(e=1e3),this._ws.close(e,t),this._ws=null,this._pingPong.disconnected(),this._resolveClosed({code:e,reason:t}))},e.prototype.sendPing=function(e){this._ws&&this._ws.send(JSON.stringify({type:"ping",data:e}))},e.prototype.connected=null,e.prototype.closed=null,e.prototype.onNotification=function(){},e.prototype._connect=function(){null===this._ws&&(this._ws=new t._.WebSocket(this._wsUrl),this._ws.onclose=this._onSocketClose.bind(this),this._ws.onerror=this._onSocketError.bind(this),this._ws.onmessage=this._onSocketMessage.bind(this),this._ws.onopen=this._onSocketOpen.bind(this),this._pingPong.startedConnecting())},e.prototype._onMessage=function(e){var t;return t=e.type,"pong"===t?void this._pingPong.receivedPong(e.data):(this._pingPong.receivedMessage(),"note"===t?void this.onNotification(e.data):"hi"===t?void this._resolveConnected(!0):void this._close(4400,"Invalid message type: "+t))},e.prototype._onSocketClose=function(e){null!==this._ws&&this.close(e.code,e.reason)},e.prototype._onSocketError=function(){null!==this._ws&&this.close(4e3,event.message)},e.prototype._onSocketMessage=function(e){var t,n,i;if(this._ws){i=e.data,n=null;try{n=JSON.parse(i)}catch(r){t=r,this.close(4400,"Invalid JSON message")}this._onMessage(n)}},e.prototype._onSocketOpen=function(){},e}()}).call(this);
(function(){var e,t,n,i,r,o;if(e=function(){function e(){}return e.prototype.setupPushManager=function(e){return this.pushRegistrationManager=new t.PushRegistrationManager(e)},e.prototype.pushRegistrationManager=null,e}(),t=new e,t.ServiceWorkerRegistration=e,t._={},"undefined"!=typeof global&&"undefined"!=typeof module&&"exports"in module)r=global,o=module.require.bind(module),module.exports=t;else if("undefined"!=typeof window&&"undefined"!=typeof navigator)r=window,o=null,window.W3gram=t;else{if("undefined"==typeof self||"undefined"==typeof navigator)throw new Error("w3gram.js loaded in an unsupported JavaScript environment.");n=self,i=self.importScripts.bind(self),self.W3gram=t}t._.global=r,t._.require=o,t._.App=function(){function e(e){var t;if(!(this.apiKey=e.key))throw new Error("The key option must be a W3gram API key");if(this.secret=e.secret||null,this.name=e.name||null,this.origin=e.origin||null,!(t=e.server))throw new Error("The server option must be a W3gram server URL");"/"===t.substring(t.length-1)&&(t=t.substring(0,t.length-1)),this.serverUrl=t,this._registerUrl=""+t+"/register"}return e.prototype.toJSON=function(){return{name:this.name,origin:this.origin,key:this.apiKey,secret:this.secret,server:this.serverUrl}},e.prototype.register=function(e,n){var i;return i={app:this.apiKey,device:e,token:n},t._.jsonRequest("POST",this._registerUrl,i).then(function(i){return function(r){return r.server=i.serverUrl,r.app=i.apiKey,r.device=e,r.token=n,new t._.DeviceRegistration(r)}}(this))},e.prototype.token=function(e){return t._.App.checkDeviceId(e).then(function(n){return function(){return n.checkCanCreateTokens().then(function(){return t._.hmac(n.secret,"device-id|"+e)})}}(this))},e.checkDeviceId=function(e){return t._.App.isValidDeviceId(e)?t._.Promise.resolve(!0):t._.Promise.reject(new t._.DOMException(t._.DOMException.SyntaxError,"Invalid device ID"))},e.isValidDeviceId=function(e){return e.length<=64?/^[A-Za-z0-9_\-]+$/.test(e):!1},e.prototype.checkCanCreateTokens=function(){return this.secret?t._.Promise.resolve(!0):t._.Promise.reject(new t._.DOMException(t._.DOMException.InvalidStateError,"Cannot generate tokens without the app secret"))},e}(),t._.DeviceRegistration=function(){function e(e){var t;this.pushUrl=e.push,this.receiverId=e.receiver,this.apiKey=e.app,this.deviceId=e.device,this.token=e.token,t=e.server,"/"===t.substring(t.length-1)&&(t=t.substring(0,t.length-1)),this.serverUrl=t,this._routeUrl=""+t+"/route"}return e.prototype.push=function(e){var n;return n={receiver:this.receiverId,message:e},t._.jsonRequest("POST",this.pushUrl,n).then(function(){return!0})},e.prototype.route=function(){var e;return e={app:this.apiKey,device:this.deviceId,receiver:this.receiverId,token:this.token},t._.jsonRequest("POST",this._routeUrl,e).then(function(e){return e.listen})},e.prototype.toJSON=function(){return{push:this.pushUrl,receiver:this.receiverId,server:this.serverUrl,app:this.apiKey,device:this.deviceId,token:this.token}},e}(),t._.DOMException=function(){function e(e,t){this.name=e,this.message=t}return e.name=null,e.NotFoundError="NotFoundError",e.InvalidStateError="InvalidStateError",e.SyntaxError="SyntaxError",e.NotFoundError="NotFoundError",e.SecurityError="SecurityError",e.NetworkError="NetworkError",e.AbortError="AbortError",e.ABORT_ERR=20,e}(),function(){var e,n,i,r,o,s,c,u,h;if(t._.hmac=function(n,r){return new t._.Promise(function(t){return t(e(i(u(n),u(r),n.length,r.length)))})},t._.require)try{n=t._.require("crypto"),n.createHmac&&(t._.hmac=function(e,i){return new t._.Promise(function(t){return t(n.createHmac("sha256",e).update(i).digest("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/\=/g,""))})})}catch(a){r=a}return i=function(e,t,n,i){var r,s,c,u;return e.length>16&&(e=o(e,n)),c=function(){var t,n;for(n=[],s=t=0;16>t;s=++t)n.push(909522486^e[s]);return n}(),u=function(){var t,n;for(n=[],s=t=0;16>t;s=++t)n.push(1549556828^e[s]);return n}(),r=o(c.concat(t),64+i),o(u.concat(r),96)},o=function(e,t){var n,i,r,o,u,h,a,l,p,_,f,d,g,v,m,w,y,P,k,T,E,S,b,N,C,M,R,O,x,I,D,U;for(e[t>>2]|=1<<31-((3&t)<<3),e[(t+8>>6<<4)+15]=t<<3,x=Array(80),n=s[0],r=s[1],u=s[2],l=s[3],_=s[4],d=s[5],v=s[6],T=s[7],S=0,N=e.length;N>S;){for(i=n,o=r,h=u,p=l,f=_,g=d,m=v,E=T,b=U=0;64>U;b=++U)16>b?O=x[b]=0|e[S+b<<2>>2]:(y=0|x[b-15<<2>>2],w=(y<<25|y>>>7)^(y<<14|y>>>18)^y>>>3,k=0|x[b-2<<2>>2],P=(k<<15|k>>>17)^(k<<13|k>>>19)^k>>>10,O=x[b]=(w+(0|x[b-7<<2>>2])|0)+(P+(0|x[b-16<<2>>2])|0)|0),a=_&d^~_&v,C=n&r^n&u^r&u,M=(n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22),R=(_<<26|_>>>6)^(_<<21|_>>>11)^(_<<7|_>>>25),I=((T+R|0)+(a+O|0)|0)+(0|c[b<<2>>2])|0,D=M+C|0,T=v,v=d,d=_,_=l+I|0,l=u,u=r,r=n,n=I+D|0;n=i+n|0,r=o+r|0,u=h+u|0,l=p+l|0,_=f+_|0,d=g+d|0,v=m+v|0,T=E+T|0,S+=16}return[n,r,u,l,_,d,v,T]},s=[],c=[],function(){var e,t,n,i,r,o,u;for(t=function(e){return 4294967296*(e-Math.floor(e))|0},r=2,u=[],n=o=0;64>o;n=++o){for(;;){for(i=!0,e=2;r>=e*e;){if(r%e===0){i=!1;break}e+=1}if(i)break;r+=1}8>n&&(s[n]=t(Math.pow(r,.5))),c[n]=t(Math.pow(r,1/3)),u.push(r+=1)}return u}(),e=function(e){var t,n,i,r,o;for(r="",t=0,i=4*e.length;i>t;)n=t,o=(e[n>>2]>>(3-(3&n)<<3)&255)<<16,n+=1,o|=(e[n>>2]>>(3-(3&n)<<3)&255)<<8,n+=1,o|=e[n>>2]>>(3-(3&n)<<3)&255,r+=h[o>>18&63],r+=h[o>>12&63],t+=1,i>t&&(r+=h[o>>6&63]),t+=1,i>t&&(r+=h[63&o]),t+=1;return r},h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",u=function(e){var t,n,i,r;for(t=[],n=i=0,r=e.length;r>=0?r>i:i>r;n=r>=0?++i:--i)t[n>>2]|=(255&e.charCodeAt(n))<<(3-(3&n)<<3);return t}}(),t._.jsonRequest=function(e,n,i){return new t._.Promise(function(r,o){var s;s=new t._.XMLHttpRequest,s.open(e,n,!0),s.onreadystatechange=function(){var e,n,i,c,u,h,a,l;if(4!==s.readyState)return!0;if(e=s.getResponseHeader("Content-Type"),e&&(a=e.indexOf(";"),-1!==a&&(e=e.substring(0,a))),u=null,h=null,"application/json"===e)try{u=JSON.parse(s.responseText||s.response)}catch(p){h=p}return l=s.status,l>=200&&300>l?h?void o(h):void r(u||{}):(0===l?(c=t._.DOMException.NetworkError,i="Could not reach Push Notification Server"):(c=t._.DOMException.SecurityError,i=u&&u.error?"Push Notification Server error: "+u.error:"Push Notification Server error: HTTP "+l),n=new t._.DOMException(c,i),0!==l&&(n.httpCode=l),void o(n))},i?(s.setRequestHeader("Content-Type","application/json; charset=utf-8"),s.send(JSON.stringify(i))):s.send()})},t._.PingPong=function(){function e(e){e||(e={}),this._silenceTimeout=e.silenceTimeoutMs||5e3,this._roundTrip=e.rttMs||2e4,this._pingSlack=e.pingSlackMs||5e3,this._nextPongNonce=0,this._pongNonce=null,this._silenceTimer=null,this._pingTimer=null,this._silenceTimerHandler=this._onSilenceTimeout.bind(this),this._pingTimerHandler=this._onPingTimeout.bind(this)}return e.prototype.startedConnecting=function(){this._resetSilenceTimer()},e.prototype.receivedPong=function(e){var t;e.nonce===this._pongNonce&&(t=Date.now()-e.ts,this._roundTrip=.2*this._roundTrip+.8*t),this._resetSilenceTimer()},e.prototype.receivedMessage=function(){this._resetSilenceTimer()},e.prototype.disconnected=function(){this._disableTimers()},e.prototype.onPing=function(){throw new Error("onPing not assigned")},e.prototype.onPingTimeout=function(){throw new Error("onPingTimeout not assigned")},e.prototype._resetSilenceTimer=function(){this._disableTimers(),this._silenceTimer=setTimeout(this._silenceTimerHandler,this._silenceTimeout)},e.prototype._onSilenceTimeout=function(){null!==this._silenceTimer&&(this._silenceTimer=null,null===this._pingTimer&&this._sendPing())},e.prototype._sendPing=function(){this._pongNonce=this._nextPongNonce,this._nextPongNonce=this._nextPongNouce+1|0,this.onPing({nonce:this._pongNonce,ts:Date.now()}),this._pingTimer=setTimeout(this._pingTimerHandler,this._roundTrip+this._pingSlack)},e.prototype._onPingTimeout=function(){null!==this._pingTimer&&(this._pingTimer=null,this._pongNonce=null,this._disableTimers(),this.onPingTimeout())},e.prototype._disableTimers=function(){null!==this._pingTimer&&(clearTimeout(this._pingTimer),this._pingTimer=null,this._pongNonce=null),null!==this._silenceTimer&&(clearTimeout(this._silenceTimer),this._silenceTimer=null)},e}(),t._.Promise="undefined"==typeof Promise?o("es6-promise-polyfill").Promise:Promise,t._.WebSocket="undefined"==typeof WebSocket?o("ws"):WebSocket,t._.XMLHttpRequest="undefined"==typeof XMLHttpRequest?o("xhr2"):XMLHttpRequest,t.PushEvent=function(){function e(e,t){this.name="PushEvent",this.target=e,this.data=t}return e}(),t._.createPushEvent=function(e,n){return new t.PushEvent(e,n)},t.PushRegistration=function(){function e(e){if(this._deviceRegistration=e,!(this._deviceRegistration instanceof t._.DeviceRegistration))throw new Error("Illegal constructor");this.registrationId=e.receiverId,this.endpoint=e.pushUrl,this._wsClient=null,this._canceled=!1,this._initialBackoff=1e3,this._nextBackoff=null,this._resolveConnected=null,this._connected=new t._.Promise(function(e){return function(t){return e._resolveConnected=t}}(this)),this._connect()}return e.prototype.registrationId=null,e.prototype.endpoint=null,e.prototype.onpush=null,e.prototype.onpushregistrationlost=null,e.prototype._cancel=function(){this._canceled=!0,this._wsClient&&this._wsClient.close(1e3,"Receiver unregistered")},e.prototype._connect=function(){return this._wsClient&&new t._.Promise.resolve(!0),this._canceled&&new t._.Promise.reject(new Error("Unregistered")),this._nextBackoff=this._initialBackoff,this._connectOnce()},e.prototype._connectOnce=function(){this._deviceRegistration.route().then(function(e){return function(n){return e._wsClient=new t._.WsClient(n),e._wsClient.onNotification=e._onNotification.bind(e),e._wsClient.closed.then(e._onWsClosed.bind(e)),e._wsClient.connected}}(this)).then(function(e){return function(){return e._nextBackoff=e._initialBackoff,e._resolveConnected(!0),!0}}(this))["catch"](function(e){return function(){var n;e._wsClient.close(4e3,"Network error"),n=e._nextBackoff,e._nextBackoff*=2,new t._.Promise(function(t){var i;return i=function(){return t(e._connect())},setTimeout(i,n)})}}(this))},e.prototype._onNotification=function(e){this._canceled||this.onpush&&this.onpush(t._.createPushEvent(this,JSON.stringify(e)))},e.prototype._onWsClosed=function(){this._wsClient=null,this._connect()},e}(),t.PushRegistrationManager=function(){function e(e){if(!e.server)throw new Error("The server option must be a W3gram server URL");if(!e.key)throw new Error("The key option must be a W3gram API key");if(!(this._deviceId=e.device))throw new Error("The device option must be a device ID");if(!(this._token=e.token))throw new Error("The token option must be the device ID's token");this._registration=null,this._app=new t._.App({server:e.server,key:e.key})}return e.prototype.register=function(){return null!==this._registration?t._.Promise.resolve(this._registration):this._app.register(this._deviceId,this._token).then(function(e){return function(n){return e._registration||(e._registration=new t.PushRegistration(n)),e._registration._connected.then(function(){return e._registration})}}(this))},e.prototype.unregister=function(){var e,n;return this._registration?(n=this._registration,this._registration=null,n._cancel(),void t._.Promise.resolve(n)):(e=new t._.DOMException(t._.DOMException.NotFoundError,"No compatible W3gram registration found on this device"),t._.Promise.reject(e))},e.prototype.getRegistration=function(){var e;return this._registration?void t._.Promise.resolve(this._registration):(e=new t._.DOMException(t._.DOMException.NotFoundError,"No compatible W3gram registration found on this device"),t._.Promise.reject(e))},e.prototype.hasPermission=function(){return t._.Promise.resolve("granted")},e}(),t._.Server=function(){function e(e){"/"===e.substring(e.length-1)&&(e=e.substring(0,e.length-1)),this.serverUrl=e,this._makUrl=""+e+"/mak",this._appsUrl=""+e+"/apps"}return e.prototype.getMak=function(){return t._.jsonRequest("GET",""+this.serverUrl+"/mak").then(function(e){return e.mak})},e.prototype.createApp=function(e,n){var i;return i={name:n.name,origin:n.origin||"*"},t._.jsonRequest("POST",this._appsUrl,{mak:e,app:i}).then(function(e){return function(n){return n.server=e.serverUrl,new t._.App(n)}}(this))},e}(),t._.WsClient=function(){function e(e,n){this._wsUrl=e,this._ws=null,this._pingPong=new t._.PingPong(n),this._pingPong.onPing=function(e){return function(t){return e.sendPing(t)}}(this),this._pingPong.onPingTimeout=function(e){return function(){return e.close(4e3,"Ping timeout")}}(this),this._resolveClosed=null,this._resolveConnected=null,this.connected=null,this.closed=new t._.Promise(function(e){return function(n){e._resolveClosed=n,e.connected=new t._.Promise(function(t){e._resolveConnected=t,e._connect()})}}(this))}return e.prototype.close=function(e,t){null!==this._ws&&(this._ws.onclose=null,this._ws.onerror=null,this._ws.onmessage=null,this._ws.onopen=null,e||(e=1e3),this._ws.close(e,t),this._ws=null,this._pingPong.disconnected(),this._resolveClosed({code:e,reason:t}))},e.prototype.sendPing=function(e){this._ws&&this._ws.send(JSON.stringify({type:"ping",data:e}))},e.prototype.connected=null,e.prototype.closed=null,e.prototype.onNotification=function(){},e.prototype._connect=function(){null===this._ws&&(this._ws=new t._.WebSocket(this._wsUrl),this._ws.onclose=this._onSocketClose.bind(this),this._ws.onerror=this._onSocketError.bind(this),this._ws.onmessage=this._onSocketMessage.bind(this),this._ws.onopen=this._onSocketOpen.bind(this),this._pingPong.startedConnecting())},e.prototype._onMessage=function(e){var t;return t=e.type,"pong"===t?void this._pingPong.receivedPong(e.data):(this._pingPong.receivedMessage(),"note"===t?void this.onNotification(e.data):"hi"===t?void this._resolveConnected(!0):void this._close(4400,"Invalid message type: "+t))},e.prototype._onSocketClose=function(e){null!==this._ws&&this.close(e.code,e.reason)},e.prototype._onSocketError=function(){null!==this._ws&&this.close(4e3,event.message)},e.prototype._onSocketMessage=function(e){var t,n,i;if(this._ws){i=e.data,n=null;try{n=JSON.parse(i)}catch(r){t=r,this.close(4400,"Invalid JSON message")}this._onMessage(n)}},e.prototype._onSocketOpen=function(){},e}()}).call(this);
//# sourceMappingURL=w3gram.min.map
{
"name": "w3gram",
"version": "0.1.0",
"version": "0.1.1",
"description": "W3gram Push Notification JavaScript Client Library",

@@ -5,0 +5,0 @@ "keywords": ["push", "notifications", "w3gram"],

+23
-85

@@ -1,94 +0,32 @@

# W3gram Server
# W3gram Client JavaScript Library
[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy)
[![Build Status](https://travis-ci.org/pwnall/w3gram-server.svg)](https://travis-ci.org/pwnall/w3gram-server)
[![API Documentation](http://img.shields.io/badge/API-Documentation-ff69b4.svg)](http://coffeedoc.info/github/pwnall/w3gram-server)
[![NPM Version](http://img.shields.io/npm/v/w3gram-server.svg)](https://www.npmjs.org/package/w3gram-server)
[![Build Status](https://travis-ci.org/pwnall/w3gram-js.svg)](https://travis-ci.org/pwnall/w3gram-js)
[![API Documentation](http://img.shields.io/badge/API-Documentation-ff69b4.svg)](http://coffeedoc.info/github/pwnall/w3gram-js)
[![NPM Version](http://img.shields.io/npm/v/w3gram-js.svg)](https://www.npmjs.org/package/w3gram-js)
This is a [node.js](http://nodejs.org/) server for the
[W3gram push notification protocol](Protocol.md).
This is a [W3c Push API](http://w3c.github.io/push-api/) polyfill that uses the
[W3gram push notification server](https://github.com/pwnall/w3gram-server). The
library works in modern browsers and in [node.js](http://nodejs.org/).
The server was designed to be deployed to [Heroku](https://www.heroku.com/)
using free resources, so it fits in a single dyno. The code has great test
coverage using [mocha](http://visionmedia.github.io/mocha/).
## Setup
## Easy Setup
```javascript
W3gram.setupPushManager({
"server": "https://your-w3gram-server.herokuapp.com",
"app": "your-api-key",
"device": "the-device-id",
"token": "token-for-the-device-id"
});
Click the ''Deploy to Heroku'' button at the top of this page to create your own
W3gram server running on Heroku. Don't worry, the project only uses free
add-ons!
Get your server's MAK and store it somewhere safely.
```bash
curl -i https://w3gram-test.herokuapp.com/mak
# Response example:
# { "mak": "3LwwhZCuqPxO_0fNATuZbOxRgXjWuCLXzOzVaH5dZ4k" }
// pushRegistrationManager returns a PushRegistrationManager that can be used
// according to the Push API spec.
W3gram.pushRegistrationManager.register();
```
Create an application and note its API key and secret.
```bash
curl -i -X POST -H 'Content-Type: application/json' \
-d '{"mak": "3LwwhZCuqPxO_0fNATuZbOxRgXjWuCLXzOzVaH5dZ4k", "app": { "name": "Testing", "origin": "*"}}' \
https://w3gram-test.herokuapp.com/apps
# Response example:
# {
# "key":"MYp4g89u3OafCtZP",
# "secret":"z7zlLM44rFWQzmgXZX0d2r7rX9mdAP7Gg56V6YjFscY",
# "origin":"*",
# "name":"Testing"
# }
```
### Manual Interaction Example
Create a token for a device ID.
```bash
echo -n "device-id|my-tablet" | \
openssl dgst -sha256 -hmac "z7zlLM44rFWQzmgXZX0d2r7rX9mdAP7Gg56V6YjFscY" \
-binary | base64
# Response example:
# Xm3U6AU4qj7z5axtldHsNvhHqlsLdMRKQQbXoiFhmDU
```
Do the routing step.
```bash
curl -i -X POST -H 'Content-Type: application/json' \
-d '{"app": "MYp4g89u3OafCtZP", "device": "my-tablet", "token": "Xm3U6AU4qj7z5axtldHsNvhHqlsLdMRKQQbXoiFhmDU"}' \
https://w3gram-test.herokuapp.com/route
# Response example:
# {
# "receiverId":"2.my-tablet.Wk3Lgc_dy0wu8smU7vHhL-Z2oDhkcF6V3Fj3O1ta2a4",
# "push":"https://w3gram-test.herokuapp.com/push",
# "listen":"wss://w3gram-test.herokuapp.com/ws/2.my-tablet.Wk3Lgc_dy0wu8smU7vHhL-Z2oDhkcF6V3Fj3O1ta2a4"
# }
```
Start a WebSocket connection:
```bash
wscat -c "wss://w3gram-test.herokuapp.com/ws/2.my-tablet.Wk3Lgc_dy0wu8smU7vHhL-Z2oDhkcF6V3Fj3O1ta2a4"
```
Send a notification:
```bash
curl -i -X POST -H 'Content-Type: application/json' \
-d '{"receiver": "2.my-tablet.Wk3Lgc_dy0wu8smU7vHhL-Z2oDhkcF6V3Fj3O1ta2a4", "message": { "data": "Hello push world" } }' \
https://w3gram-test.herokuapp.com/push
```
## Development Setup
Install all dependencies and create PostgreSQL database for development and
testing.
Install all dependencies and create the PostgreSQL database used by the W3gram
server in the test suite.

@@ -98,9 +36,9 @@ ```bash

createdb w3gram_test
createdb w3gram_dev
```
Run the server in developmentm mode.
Run tests.
```bash
npm start
cake test
cake webtest
```

@@ -107,0 +45,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet