@pelican-identity/auth-core 1.2.3 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,0BAA0B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const BASEURL = "http://localhost:8080";
2
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,uBAAuB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EAGpB,MAAM,gBAAgB,CAAC;AAYxB,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;AAMxC,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IAEnD,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,UAAU,CAAuB;IAEzC,OAAO,CAAC,iBAAiB,CAAC,CAAa;IAEvC,OAAO,CAAC,SAAS,CAEV;IAEP,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;gBAEzC,MAAM,EAAE,iBAAiB;IAsBrC,EAAE,CAAC,CAAC,SAAS,MAAM,mBAAmB,EACpC,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAWhC,KAAK;IAqCX,IAAI;YAOU,aAAa;YAiBb,cAAc;IA+B5B,OAAO,CAAC,aAAa;IAqCrB,OAAO,CAAC,iBAAiB;YAwCX,cAAc;IA4B5B,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,SAAS;IAyBjB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,YAAY;IAMpB,OAAO;IAMP,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,IAAI;CAIb"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EAGpB,MAAM,gBAAgB,CAAC;AAYxB,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;AAMxC,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IAEnD,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,UAAU,CAAuB;IAEzC,OAAO,CAAC,iBAAiB,CAAC,CAAa;IAEvC,OAAO,CAAC,SAAS,CAEV;IAEP,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;gBAEzC,MAAM,EAAE,iBAAiB;IAsBrC,EAAE,CAAC,CAAC,SAAS,MAAM,mBAAmB,EACpC,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAWhC,KAAK;IAqCX,IAAI;YAOU,aAAa;YAiBb,cAAc;IAkC5B,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,iBAAiB;YAwCX,cAAc;IA4B5B,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,YAAY;IAMpB,OAAO;IAMP,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,IAAI;CAIb"}
@@ -87,15 +87,17 @@ export class PelicanAuthentication {
87
87
  this.emit("deeplink", `pelicanvault://auth/deep-link?data=${encodeURIComponent(JSON.stringify(payload))}`);
88
88
  }
89
89
  else {
90
- const qr = await QRCode.toDataURL(JSON.stringify(payload));
90
+ const qr = await QRCode.toDataURL(JSON.stringify(payload), {
91
+ type: "image/png",
92
+ scale: 3,
93
+ color: { light: "#FFFFF5", dark: "#121212" },
94
+ });
91
95
  this.emit("qr", qr);
92
96
  }
93
97
  }
94
98
  handleMessage(msg) {
95
- console.log(msg);
96
99
  switch (msg.type) {
97
100
  case "paired":
98
- console.log("Paired");
99
101
  this.stateMachine.transition("paired");
100
102
  this.transport.send({
101
103
  type: "authenticate",
@@ -199,21 +201,18 @@ export class PelicanAuthentication {
199
201
  authType: this.config.authType,
200
202
  });
201
203
  }
202
- setTimeout(() => {
203
- this.transport?.close();
204
- }, 150);
204
+ this.transport?.close();
205
205
  clearAuthSession();
206
206
  this.resetSession();
207
207
  if (!this.config.continuousMode) {
208
208
  this.detachVisibilityRecovery();
209
209
  }
210
- this.stateMachine.transition(success ? "confirmed" : "terminated");
210
+ this.stateMachine.transition(success ? "confirmed" : "idle");
211
211
  }
212
212
  restartIfContinuous() {
213
+ this.stateMachine.transition("idle");
213
214
  if (!this.config.continuousMode)
214
215
  return;
215
- this.terminate(false);
216
- this.stateMachine.transition("idle");
217
216
  setTimeout(() => {
218
217
  this.start();
219
218
  }, 150);
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAO5B,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,gBAAgB,GAEjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQvC,MAAM,OAAO,qBAAqB;IAgBhC,YAAY,MAAyB;QAfpB,WAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAC7B,iBAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QAG3C,cAAS,GAAG,EAAE,CAAC;QACf,eAAU,GAAkB,IAAI,CAAC;QAIjC,cAAS,GAEb,EAAE,CAAC;QAKL,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAE1D,IAAI,CAAC,MAAM,GAAG;YACZ,cAAc,EAAE,KAAK;YACrB,WAAW,EAAE,KAAK;YAClB,GAAG,MAAM;SACV,CAAC;QAGF,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAQD,EAAE,CACA,KAAQ,EACR,EAAoC;;QAEpC,MAAA,IAAI,CAAC,SAAS,EAAC,KAAK,SAAL,KAAK,IAAM,IAAI,GAAG,EAAE,EAAC;QACpC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAMD,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,KAAK,MAAM;YAAE,OAAO;QAEjD,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QAE7C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YAGzC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;YACrD,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YAE3D,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC;gBAC7B,MAAM,EAAE,GAAG,EAAE;oBAEX,IAAI,CAAC,SAAU,CAAC,IAAI,CAAC;wBACnB,IAAI,EAAE,UAAU;wBAChB,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,GAAG,IAAI,CAAC,MAAM;qBACf,CAAC,CAAC;oBACH,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;gBAChD,CAAC;gBACD,SAAS,EAAE,CAAC,GAAmB,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;gBAC3D,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;aACnE,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9B,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAKD,IAAI;QACF,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAKO,KAAK,CAAC,aAAa;QACzB,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QACvD,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,OAAO,qBAAqB,SAAS,cAAc,QAAQ,eAAe,SAAS,EAAE,CACzF,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAKO,KAAK,CAAC,cAAc;QAC1B,MAAM,OAAO,GAAG;YACd,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAChC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAChC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;SAC1B,CAAC;QAEF,MAAM,WAAW,GACf,IAAI,CAAC,MAAM,CAAC,WAAW;YACvB,CAAC,sBAAsB,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAEpD,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAEpC,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,KAAM,CAAC,CAAC;YAC9D,IAAI,CAAC,IAAI,CACP,UAAU,EACV,sCAAsC,kBAAkB,CACtD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CACxB,EAAE,CACJ,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;gBACzD,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;aAC7C,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAGO,aAAa,CAAC,GAAmB;QACvC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;gBACvC,IAAI,CAAC,SAAU,CAAC,IAAI,CAAC;oBACnB,IAAI,EAAE,cAAc;oBACpB,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,GAAG,IAAI,CAAC,MAAM;oBACd,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;iBAC1B,CAAC,CAAC;gBACH,OAAO;YAET,KAAK,oBAAoB;gBAEvB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;gBAC5B,OAAO;YAET,KAAK,kBAAkB;gBACrB,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC,CAAC;gBACxE,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,OAAO;YAET,KAAK,WAAW;gBAEd,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACrB,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,OAAO;QACX,CAAC;IACH,CAAC;IAKO,iBAAiB,CAAC,GAAmB;QAC3C,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;YACvD,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;gBAC7C,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE;gBACnD,SAAS,EAAE,IAAI,CAAC,UAAU;aAC3B,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;gBACpD,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAmB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAErD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7B,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAG9C,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;gBACnB,IAAI,EAAE,SAAS;gBACf,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC;IAOO,KAAK,CAAC,cAAc,CAAC,MAAmB;QAC9C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,OAAO,uBAAuB,MAAM,CAAC,SAAS,EAAE,CACpD,CAAC;YAEF,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAEhD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;gBAC7C,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;gBACrD,SAAS,EAAE,MAAM,CAAC,UAAU;aAC7B,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC;gBAC7C,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAmB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACrD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7B,gBAAgB,EAAE,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAChD,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,wBAAwB;QAC9B,IAAI,CAAC,iBAAiB,GAAG,KAAK,IAAI,EAAE;YAClC,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS;gBAAE,OAAO;YAEnD,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC;QAEF,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACxE,CAAC;IAEO,wBAAwB;QAC9B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACzE,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;QACrC,CAAC;IACH,CAAC;IAGO,SAAS,CAAC,OAAgB;QAChC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;gBACnB,IAAI,EAAE,mBAAmB;gBACzB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;gBAChC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;gBAChC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;aAC/B,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;QACxB,gBAAgB,EAAE,CAAC;QACnB,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAChC,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC;IAEO,mBAAmB;QACzB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc;YAAE,OAAO;QACxC,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAGD,OAAO;QACL,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACtB,CAAC;IAEO,IAAI,CACV,KAAQ,EACR,OAA+B;QAE/B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,CAAC;IAEO,IAAI,CAAC,GAAU;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;CACF"}
package/dist/index.d.mts CHANGED
@@ -155,8 +155,13 @@ type TransportHandlers = {
155
155
  declare class Transport {
156
156
  private socket?;
157
157
  private handlers;
158
+ private reconnectAttempts;
159
+ private maxReconnectAttempts;
160
+ private isExplicitlyClosed;
161
+ private url?;
158
162
  constructor(handlers: TransportHandlers);
159
163
  connect(url: string): void;
164
+ private attemptReconnect;
160
165
  send(payload: ISocketMessage): void;
161
166
  close(): void;
162
167
  }
package/dist/index.d.ts CHANGED
@@ -155,8 +155,13 @@ type TransportHandlers = {
155
155
  declare class Transport {
156
156
  private socket?;
157
157
  private handlers;
158
+ private reconnectAttempts;
159
+ private maxReconnectAttempts;
160
+ private isExplicitlyClosed;
161
+ private url?;
158
162
  constructor(handlers: TransportHandlers);
159
163
  connect(url: string): void;
164
+ private attemptReconnect;
160
165
  send(payload: ISocketMessage): void;
161
166
  close(): void;
162
167
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,477 +1,8 @@
1
- 'use strict';
2
-
3
- var nacl = require('tweetnacl');
4
- var tweetnaclUtil = require('tweetnacl-util');
5
- var QRCode = require('qrcode');
6
-
7
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
-
9
- var nacl__default = /*#__PURE__*/_interopDefault(nacl);
10
- var QRCode__default = /*#__PURE__*/_interopDefault(QRCode);
11
-
12
- // src/utilities/crypto.ts
13
- var CryptoService = class {
14
- generateSymmetricKey() {
15
- const key = nacl__default.default.randomBytes(32);
16
- return tweetnaclUtil.encodeBase64(key);
17
- }
18
- /**
19
- * Encrypt with symmetric key (secret-key encryption)
20
- * Use this when both parties share the same secret key
21
- * @param plaintext - Message to encrypt
22
- * @param keyString - Symmetric key (base64)
23
- * @returns Encrypted message with nonce
24
- */
25
- encryptSymmetric({
26
- plaintext,
27
- keyString
28
- }) {
29
- const key = tweetnaclUtil.decodeBase64(keyString);
30
- const nonce = nacl__default.default.randomBytes(24);
31
- const messageBytes = new TextEncoder().encode(plaintext);
32
- const ciphertext = nacl__default.default.secretbox(messageBytes, nonce, key);
33
- return {
34
- cipher: tweetnaclUtil.encodeBase64(ciphertext),
35
- nonce: tweetnaclUtil.encodeBase64(nonce)
36
- };
37
- }
38
- /**
39
- * Decrypt with symmetric key
40
- * @param encrypted - Encrypted message with nonce
41
- * @param keyString - Symmetric key (base64)
42
- * @returns Decrypted plaintext
43
- */
44
- decryptSymmetric({
45
- encrypted,
46
- keyString
47
- }) {
48
- try {
49
- const key = tweetnaclUtil.decodeBase64(keyString);
50
- const ciphertextBytes = tweetnaclUtil.decodeBase64(encrypted.cipher);
51
- const nonceBytes = tweetnaclUtil.decodeBase64(encrypted.nonce);
52
- const decrypted = nacl__default.default.secretbox.open(ciphertextBytes, nonceBytes, key);
53
- if (!decrypted) {
54
- throw new Error("Decryption failed - invalid key or corrupted data");
55
- }
56
- const decoded = new TextDecoder().decode(decrypted);
57
- return decoded;
58
- } catch (error) {
59
- console.error("Decryption failed", error);
60
- return null;
61
- }
62
- }
63
- };
64
- var crypto_default = CryptoService;
65
-
66
- // src/utilities/storage.ts
67
- var AuthStorage = class {
68
- constructor() {
69
- this.prefix = "pelican_auth_";
70
- this.defaultTTL = 5 * 60 * 1e3;
71
- // 5 minutes
72
- this.memoryCache = /* @__PURE__ */ new Map();
73
- }
74
- /**
75
- * Store auth session with automatic cleanup
76
- */
77
- set(key, value, options = {}) {
78
- const { ttlMs = this.defaultTTL, useSessionStorage = true } = options;
79
- const expiresAt = Date.now() + ttlMs;
80
- const data = { value, expiresAt };
81
- if (useSessionStorage) {
82
- try {
83
- sessionStorage.setItem(`${this.prefix}${key}`, JSON.stringify(data));
84
- } catch (error) {
85
- console.warn("SessionStorage unavailable, using memory:", error);
86
- this.setMemory(key, data);
87
- }
88
- } else {
89
- this.setMemory(key, data);
90
- }
91
- }
92
- /**
93
- * Get stored value if not expired
94
- */
95
- get(key) {
96
- try {
97
- const stored = sessionStorage.getItem(`${this.prefix}${key}`);
98
- if (stored) {
99
- const data = JSON.parse(stored);
100
- if (Date.now() > data.expiresAt) {
101
- this.remove(key);
102
- return null;
103
- }
104
- return data.value;
105
- }
106
- } catch (error) {
107
- }
108
- return this.getMemory(key);
109
- }
110
- /**
111
- * Remove specific key
112
- */
113
- remove(key) {
114
- try {
115
- sessionStorage.removeItem(`${this.prefix}${key}`);
116
- } catch (error) {
117
- }
118
- this.memoryCache.delete(key);
119
- }
120
- /**
121
- * Clear all auth data
122
- */
123
- clear() {
124
- try {
125
- Object.keys(sessionStorage).forEach((key) => {
126
- if (key.startsWith(this.prefix)) {
127
- sessionStorage.removeItem(key);
128
- }
129
- });
130
- } catch (error) {
131
- }
132
- this.memoryCache.clear();
133
- }
134
- // ========================================
135
- // Memory cache helpers
136
- // ========================================
137
- setMemory(key, data) {
138
- this.memoryCache.set(key, data);
139
- const ttl = data.expiresAt - Date.now();
140
- setTimeout(() => {
141
- this.memoryCache.delete(key);
142
- }, ttl);
143
- }
144
- getMemory(key) {
145
- const data = this.memoryCache.get(key);
146
- if (!data) return null;
147
- if (Date.now() > data.expiresAt) {
148
- this.memoryCache.delete(key);
149
- return null;
150
- }
151
- return data.value;
152
- }
153
- };
154
- var storage = new AuthStorage();
155
- var storeAuthSession = (sessionId, sessionKey, ttlMs) => {
156
- storage.set("session", { sessionId, sessionKey }, { ttlMs });
157
- };
158
- var getAuthSession = () => {
159
- return storage.get("session");
160
- };
161
- var clearAuthSession = () => {
162
- storage.remove("session");
163
- };
164
- var clearAllAuthData = () => {
165
- storage.clear();
166
- };
167
-
168
- // src/utilities/stateMachine.ts
169
- var StateMachine = class {
170
- constructor() {
171
- this.state = "idle";
172
- this.listeners = /* @__PURE__ */ new Set();
173
- }
174
- get current() {
175
- return this.state;
176
- }
177
- transition(next) {
178
- this.state = next;
179
- this.listeners.forEach((l) => l(next));
180
- }
181
- subscribe(fn) {
182
- this.listeners.add(fn);
183
- return () => this.listeners.delete(fn);
184
- }
185
- };
186
-
187
- // src/utilities/transport.ts
188
- var Transport = class {
189
- constructor(handlers) {
190
- this.handlers = handlers;
191
- }
192
- connect(url) {
193
- this.socket = new WebSocket(url);
194
- this.socket.onopen = () => this.handlers.onOpen?.();
195
- this.socket.onmessage = (e) => this.handlers.onMessage?.(e.data);
196
- this.socket.onerror = (e) => this.handlers.onError?.(e);
197
- this.socket.onclose = (e) => this.handlers.onClose?.(e);
198
- }
199
- send(payload) {
200
- if (this.socket?.readyState === WebSocket.OPEN) {
201
- this.socket.send(JSON.stringify(payload));
202
- }
203
- }
204
- close() {
205
- this.socket?.close();
206
- }
207
- };
208
-
209
- // src/constants.ts
210
- var BASEURL = "http://localhost:8080";
211
-
212
- // src/engine/engine.ts
213
- var PelicanAuthentication = class {
214
- constructor(config) {
215
- this.crypto = new crypto_default();
216
- this.stateMachine = new StateMachine();
217
- this.sessionId = "";
218
- this.sessionKey = null;
219
- this.listeners = {};
220
- if (!config.publicKey) throw new Error("Missing publicKey");
221
- if (!config.projectId) throw new Error("Missing projectId");
222
- if (!config.authType) throw new Error("Missing authType");
223
- this.config = {
224
- continuousMode: false,
225
- forceQRCode: false,
226
- ...config
227
- };
228
- this.stateMachine.subscribe((s) => this.emit("state", s));
229
- this.attachVisibilityRecovery();
230
- }
231
- /* -------------------- public API -------------------- */
232
- /**
233
- * Subscribe to SDK events (qr, deeplink, success, error, state)
234
- * @returns Unsubscribe function
235
- */
236
- on(event, cb) {
237
- var _a;
238
- (_a = this.listeners)[event] ?? (_a[event] = /* @__PURE__ */ new Set());
239
- this.listeners[event].add(cb);
240
- return () => this.listeners[event].delete(cb);
241
- }
242
- /**
243
- * Initializes the authentication flow.
244
- * Fetches a relay, establishes a WebSocket, and generates the E2EE session key.
245
- */
246
- async start() {
247
- if (this.stateMachine.current !== "idle") return;
248
- this.resetSession();
249
- this.stateMachine.transition("initializing");
250
- try {
251
- const relay = await this.fetchRelayUrl();
252
- this.sessionKey = this.crypto.generateSymmetricKey();
253
- this.sessionId = crypto.randomUUID() + crypto.randomUUID();
254
- this.transport = new Transport({
255
- onOpen: () => {
256
- this.transport.send({
257
- type: "register",
258
- sessionID: this.sessionId,
259
- ...this.config
260
- });
261
- this.stateMachine.transition("awaiting-pair");
262
- },
263
- onMessage: (msg) => this.handleMessage(msg),
264
- onError: () => this.fail(new Error("WebSocket connection failed"))
265
- });
266
- this.transport.connect(relay);
267
- await this.emitEntryPoint();
268
- } catch (err) {
269
- this.fail(err instanceof Error ? err : new Error("Start failed"));
270
- }
271
- }
272
- /**
273
- * Manually stops the authentication process and closes connections.
274
- */
275
- stop() {
276
- this.terminate(false);
277
- }
278
- /* -------------------- internals -------------------- */
279
- /** Fetches the WebSocket Relay URL from the backend */
280
- async fetchRelayUrl() {
281
- const { publicKey, projectId, authType } = this.config;
282
- const res = await fetch(
283
- `${BASEURL}/relay?public_key=${publicKey}&auth_type=${authType}&project_id=${projectId}`
284
- );
285
- if (!res.ok) {
286
- throw new Error("Failed to fetch relay URL");
287
- }
288
- const json = await res.json();
289
- return json.relay_url;
290
- }
291
- /**
292
- * Decides whether to show a QR code (Desktop) or a Deep Link (Mobile).
293
- */
294
- async emitEntryPoint() {
295
- const payload = {
296
- sessionID: this.sessionId,
297
- sessionKey: this.sessionKey,
298
- publicKey: this.config.publicKey,
299
- authType: this.config.authType,
300
- projectId: this.config.projectId,
301
- url: window.location.href
302
- };
303
- const shouldUseQR = this.config.forceQRCode || !/Android|iPhone|iPad/i.test(navigator.userAgent);
304
- if (!shouldUseQR && this.sessionKey) {
305
- storeAuthSession(this.sessionId, this.sessionKey, 5 * 6e4);
306
- this.emit(
307
- "deeplink",
308
- `pelicanvault://auth/deep-link?data=${encodeURIComponent(
309
- JSON.stringify(payload)
310
- )}`
311
- );
312
- } else {
313
- const qr = await QRCode__default.default.toDataURL(JSON.stringify(payload));
314
- this.emit("qr", qr);
315
- }
316
- }
317
- /** Main WebSocket message router */
318
- handleMessage(msg) {
319
- console.log(msg);
320
- switch (msg.type) {
321
- case "paired":
322
- console.log("Paired");
323
- this.stateMachine.transition("paired");
324
- this.transport.send({
325
- type: "authenticate",
326
- sessionID: this.sessionId,
327
- ...this.config,
328
- url: window.location.href
329
- });
330
- return;
331
- case "phone-auth-success":
332
- this.handleAuthSuccess(msg);
333
- return;
334
- case "phone-terminated":
335
- this.fail(new Error("Authenticating device terminated the connection"));
336
- this.restartIfContinuous();
337
- return;
338
- case "confirmed":
339
- this.terminate(true);
340
- this.restartIfContinuous();
341
- return;
342
- }
343
- }
344
- /**
345
- * Decrypts the identity payload received from the phone using the session key.
346
- */
347
- handleAuthSuccess(msg) {
348
- if (!this.sessionKey || !msg.cipher || !msg.nonce) {
349
- this.fail(new Error("Invalid authentication payload"));
350
- this.restartIfContinuous();
351
- return;
352
- }
353
- try {
354
- const decrypted = this.crypto.decryptSymmetric({
355
- encrypted: { cipher: msg.cipher, nonce: msg.nonce },
356
- keyString: this.sessionKey
357
- });
358
- if (!decrypted) {
359
- this.fail(new Error("Invalid authentication data"));
360
- this.restartIfContinuous();
361
- return;
362
- }
363
- const result = JSON.parse(decrypted);
364
- this.emit("success", result);
365
- this.stateMachine.transition("authenticated");
366
- this.transport?.send({
367
- type: "confirm",
368
- sessionID: this.sessionId
369
- });
370
- } catch {
371
- this.fail(new Error("Failed to decrypt authentication data"));
372
- this.restartIfContinuous();
373
- }
374
- }
375
- /**
376
- * Logic to handle users returning to the browser tab after using the mobile app.
377
- * Checks the server for a completed session that might have finished while in background.
378
- */
379
- async getCachedEntry(cached) {
380
- try {
381
- const res = await fetch(
382
- `${BASEURL}/session?session_id=${cached.sessionId}`
383
- );
384
- if (!res.ok) throw new Error("Invalid session");
385
- const data = await res.json();
386
- const decrypted = this.crypto.decryptSymmetric({
387
- encrypted: { cipher: data.cipher, nonce: data.nonce },
388
- keyString: cached.sessionKey
389
- });
390
- if (!decrypted) {
391
- this.fail(new Error("Invalid session data"));
392
- this.restartIfContinuous();
393
- return;
394
- }
395
- const result = JSON.parse(decrypted);
396
- this.emit("success", result);
397
- clearAuthSession();
398
- } catch {
399
- this.fail(new Error("Session recovery failed"));
400
- this.restartIfContinuous();
401
- }
402
- }
403
- attachVisibilityRecovery() {
404
- this.visibilityHandler = async () => {
405
- if (document.visibilityState !== "visible") return;
406
- const cached = getAuthSession();
407
- if (!cached) return;
408
- await this.getCachedEntry(cached);
409
- };
410
- document.addEventListener("visibilitychange", this.visibilityHandler);
411
- }
412
- detachVisibilityRecovery() {
413
- if (this.visibilityHandler) {
414
- document.removeEventListener("visibilitychange", this.visibilityHandler);
415
- this.visibilityHandler = void 0;
416
- }
417
- }
418
- /** Cleans up the current session state */
419
- terminate(success) {
420
- if (!this.transport) return;
421
- if (!success) {
422
- this.transport?.send({
423
- type: "client-terminated",
424
- sessionID: this.sessionId,
425
- projectId: this.config.projectId,
426
- publicKey: this.config.publicKey,
427
- authType: this.config.authType
428
- });
429
- }
430
- setTimeout(() => {
431
- this.transport?.close();
432
- }, 150);
433
- clearAuthSession();
434
- this.resetSession();
435
- if (!this.config.continuousMode) {
436
- this.detachVisibilityRecovery();
437
- }
438
- this.stateMachine.transition(success ? "confirmed" : "terminated");
439
- }
440
- restartIfContinuous() {
441
- if (!this.config.continuousMode) return;
442
- this.terminate(false);
443
- this.stateMachine.transition("idle");
444
- setTimeout(() => {
445
- this.start();
446
- }, 150);
447
- }
448
- resetSession() {
449
- this.sessionId = "";
450
- this.sessionKey = null;
451
- }
452
- /** Completely destroys the instance and removes all listeners */
453
- destroy() {
454
- this.detachVisibilityRecovery();
455
- this.transport?.close();
456
- this.listeners = {};
457
- }
458
- emit(event, payload) {
459
- this.listeners[event]?.forEach((cb) => cb(payload));
460
- }
461
- fail(err) {
462
- this.emit("error", err);
463
- this.stateMachine.transition("error");
464
- }
465
- };
466
-
467
- exports.BASEURL = BASEURL;
468
- exports.CryptoService = CryptoService;
469
- exports.PelicanAuthentication = PelicanAuthentication;
470
- exports.StateMachine = StateMachine;
471
- exports.Transport = Transport;
472
- exports.clearAllAuthData = clearAllAuthData;
473
- exports.clearAuthSession = clearAuthSession;
474
- exports.getAuthSession = getAuthSession;
475
- exports.storeAuthSession = storeAuthSession;
476
- //# sourceMappingURL=index.js.map
1
+ export * from "./types/types";
2
+ export { PelicanAuthentication } from "./engine/engine";
3
+ export { CryptoService } from "./utilities/crypto";
4
+ export { StateMachine } from "./utilities/stateMachine";
5
+ export { Transport } from "./utilities/transport";
6
+ export * from "./utilities/storage";
7
+ export { BASEURL } from "./constants";
477
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utilities/crypto.ts","../src/utilities/storage.ts","../src/utilities/stateMachine.ts","../src/utilities/transport.ts","../src/constants.ts","../src/engine/engine.ts"],"names":["nacl","encodeBase64","decodeBase64","QRCode"],"mappings":"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","file":"index.js","sourcesContent":["import nacl from \"tweetnacl\";\nimport { decodeBase64, encodeBase64 } from \"tweetnacl-util\";\n\ninterface EncryptedMessage {\n cipher: string; // Base64 encoded\n nonce: string; // Base64 encoded\n}\n\nexport class CryptoService {\n generateSymmetricKey(): string {\n const key = nacl.randomBytes(32);\n return encodeBase64(key);\n }\n\n /**\n * Encrypt with symmetric key (secret-key encryption)\n * Use this when both parties share the same secret key\n * @param plaintext - Message to encrypt\n * @param keyString - Symmetric key (base64)\n * @returns Encrypted message with nonce\n */\n encryptSymmetric({\n plaintext,\n keyString,\n }: {\n plaintext: string;\n keyString: string;\n }): EncryptedMessage {\n const key = decodeBase64(keyString);\n const nonce = nacl.randomBytes(24);\n\n const messageBytes = new TextEncoder().encode(plaintext);\n\n const ciphertext = nacl.secretbox(messageBytes, nonce, key);\n\n return {\n cipher: encodeBase64(ciphertext),\n nonce: encodeBase64(nonce),\n };\n }\n\n /**\n * Decrypt with symmetric key\n * @param encrypted - Encrypted message with nonce\n * @param keyString - Symmetric key (base64)\n * @returns Decrypted plaintext\n */\n decryptSymmetric({\n encrypted,\n keyString,\n }: {\n encrypted: EncryptedMessage;\n keyString: string;\n }): string | null {\n try {\n const key = decodeBase64(keyString);\n const ciphertextBytes = decodeBase64(encrypted.cipher);\n const nonceBytes = decodeBase64(encrypted.nonce);\n\n const decrypted = nacl.secretbox.open(ciphertextBytes, nonceBytes, key);\n\n if (!decrypted) {\n throw new Error(\"Decryption failed - invalid key or corrupted data\");\n }\n\n const decoded = new TextDecoder().decode(decrypted);\n return decoded;\n } catch (error) {\n console.error(\"Decryption failed\", error);\n return null;\n }\n }\n}\n\nexport default CryptoService;\nexport type { EncryptedMessage };\n","// hybridStorage.ts\n/**\n * Hybrid storage: Try sessionStorage first, fallback to memory\n * Best of both worlds - survives page refresh but auto-cleans\n */\n\ninterface StorageOptions {\n ttlMs?: number;\n useSessionStorage?: boolean;\n}\n\nclass AuthStorage {\n private readonly prefix = \"pelican_auth_\";\n private readonly defaultTTL = 5 * 60 * 1000; // 5 minutes\n private memoryCache: Map<string, { value: any; expiresAt: number }> =\n new Map();\n\n /**\n * Store auth session with automatic cleanup\n */\n set(key: string, value: any, options: StorageOptions = {}): void {\n const { ttlMs = this.defaultTTL, useSessionStorage = true } = options;\n\n const expiresAt = Date.now() + ttlMs;\n const data = { value, expiresAt };\n\n // Try sessionStorage first\n if (useSessionStorage) {\n try {\n sessionStorage.setItem(`${this.prefix}${key}`, JSON.stringify(data));\n } catch (error) {\n console.warn(\"SessionStorage unavailable, using memory:\", error);\n this.setMemory(key, data);\n }\n } else {\n this.setMemory(key, data);\n }\n }\n\n /**\n * Get stored value if not expired\n */\n get(key: string): any | null {\n // Try sessionStorage first\n try {\n const stored = sessionStorage.getItem(`${this.prefix}${key}`);\n if (stored) {\n const data = JSON.parse(stored);\n\n // Check expiration\n if (Date.now() > data.expiresAt) {\n this.remove(key);\n return null;\n }\n\n return data.value;\n }\n } catch (error) {\n // Fallback to memory\n }\n\n // Try memory cache\n return this.getMemory(key);\n }\n\n /**\n * Remove specific key\n */\n remove(key: string): void {\n try {\n sessionStorage.removeItem(`${this.prefix}${key}`);\n } catch (error) {\n // Ignore\n }\n this.memoryCache.delete(key);\n }\n\n /**\n * Clear all auth data\n */\n clear(): void {\n // Clear sessionStorage\n try {\n Object.keys(sessionStorage).forEach((key) => {\n if (key.startsWith(this.prefix)) {\n sessionStorage.removeItem(key);\n }\n });\n } catch (error) {\n // Ignore\n }\n\n // Clear memory\n this.memoryCache.clear();\n }\n\n // ========================================\n // Memory cache helpers\n // ========================================\n\n private setMemory(\n key: string,\n data: { value: any; expiresAt: number }\n ): void {\n this.memoryCache.set(key, data);\n\n // Schedule cleanup\n const ttl = data.expiresAt - Date.now();\n setTimeout(() => {\n this.memoryCache.delete(key);\n }, ttl);\n }\n\n private getMemory(key: string): any | null {\n const data = this.memoryCache.get(key);\n if (!data) return null;\n\n if (Date.now() > data.expiresAt) {\n this.memoryCache.delete(key);\n return null;\n }\n\n return data.value;\n }\n}\n\n// Singleton instance\nconst storage = new AuthStorage();\n\n// ========================================\n// Convenience functions for auth flow\n// ========================================\n\nexport interface AuthSession {\n sessionId: string;\n sessionKey: string;\n}\n\nexport const storeAuthSession = (\n sessionId: string,\n sessionKey: string,\n ttlMs?: number\n): void => {\n storage.set(\"session\", { sessionId, sessionKey }, { ttlMs });\n};\n\nexport const getAuthSession = (): AuthSession | null => {\n return storage.get(\"session\");\n};\n\nexport const clearAuthSession = (): void => {\n storage.remove(\"session\");\n};\n\nexport const clearAllAuthData = (): void => {\n storage.clear();\n};\n\nexport default storage;\n","import type { PelicanAuthState } from \"../types/types\";\n\nexport class StateMachine {\n private state: PelicanAuthState = \"idle\";\n private listeners = new Set<(s: PelicanAuthState) => void>();\n\n get current() {\n return this.state;\n }\n\n transition(next: PelicanAuthState) {\n this.state = next;\n this.listeners.forEach((l) => l(next));\n }\n\n subscribe(fn: (s: PelicanAuthState) => void) {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n}\n","import { ISocketMessage } from \"../types/types\";\n\ntype TransportHandlers = {\n onOpen?: () => void;\n onMessage?: (msg: ISocketMessage) => void;\n onError?: (err: Event) => void;\n onClose?: (ev: CloseEvent) => void;\n};\n\ninterface PelicanMessageEvent extends MessageEvent {\n data: ISocketMessage;\n}\nexport class Transport {\n private socket?: WebSocket;\n private handlers: TransportHandlers;\n\n constructor(handlers: TransportHandlers) {\n this.handlers = handlers;\n }\n\n connect(url: string) {\n this.socket = new WebSocket(url);\n\n this.socket.onopen = () => this.handlers.onOpen?.();\n this.socket.onmessage = (e: PelicanMessageEvent) =>\n this.handlers.onMessage?.(e.data);\n this.socket.onerror = (e: Event) => this.handlers.onError?.(e);\n this.socket.onclose = (e: CloseEvent) => this.handlers.onClose?.(e);\n }\n\n send(payload: ISocketMessage) {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify(payload));\n }\n }\n\n close() {\n this.socket?.close();\n }\n}\n","export const BASEURL = \"http://localhost:8080\";\n","import CryptoService from \"../utilities/crypto\";\nimport QRCode from \"qrcode\";\nimport {\n PelicanAuthConfig,\n PelicanAuthEventMap,\n ISocketMessage,\n IdentityResult,\n} from \"../types/types\";\nimport {\n storeAuthSession,\n getAuthSession,\n clearAuthSession,\n AuthSession,\n} from \"../utilities/storage\";\nimport { StateMachine } from \"../utilities/stateMachine\";\nimport { Transport } from \"../utilities/transport\";\n\nimport { BASEURL } from \"../constants\";\n\ntype Listener<T> = (payload: T) => void;\n\n/**\n * PelicanAuth SDK\n * Handles cross-device authentication via WebSockets and E2EE (End-to-End Encryption).\n */\nexport class PelicanAuthentication {\n private readonly crypto = new CryptoService();\n private readonly stateMachine = new StateMachine();\n\n private transport?: Transport;\n private sessionId = \"\";\n private sessionKey: string | null = null;\n\n private visibilityHandler?: () => void;\n\n private listeners: {\n [K in keyof PelicanAuthEventMap]?: Set<Listener<any>>;\n } = {};\n\n private readonly config: Required<PelicanAuthConfig>;\n\n constructor(config: PelicanAuthConfig) {\n if (!config.publicKey) throw new Error(\"Missing publicKey\");\n if (!config.projectId) throw new Error(\"Missing projectId\");\n if (!config.authType) throw new Error(\"Missing authType\");\n\n this.config = {\n continuousMode: false,\n forceQRCode: false,\n ...config,\n };\n\n // Sync internal state machine changes with the 'state' event\n this.stateMachine.subscribe((s) => this.emit(\"state\", s));\n this.attachVisibilityRecovery();\n }\n\n /* -------------------- public API -------------------- */\n\n /**\n * Subscribe to SDK events (qr, deeplink, success, error, state)\n * @returns Unsubscribe function\n */\n on<K extends keyof PelicanAuthEventMap>(\n event: K,\n cb: Listener<PelicanAuthEventMap[K]>\n ) {\n this.listeners[event] ??= new Set();\n this.listeners[event]!.add(cb);\n return () => this.listeners[event]!.delete(cb);\n }\n\n /**\n * Initializes the authentication flow.\n * Fetches a relay, establishes a WebSocket, and generates the E2EE session key.\n */\n async start() {\n if (this.stateMachine.current !== \"idle\") return;\n\n this.resetSession();\n this.stateMachine.transition(\"initializing\");\n\n try {\n const relay = await this.fetchRelayUrl();\n\n // Generate a fresh symmetric key for this specific session\n this.sessionKey = this.crypto.generateSymmetricKey();\n this.sessionId = crypto.randomUUID() + crypto.randomUUID();\n\n this.transport = new Transport({\n onOpen: () => {\n // Register this browser session with the relay\n this.transport!.send({\n type: \"register\",\n sessionID: this.sessionId,\n ...this.config,\n });\n this.stateMachine.transition(\"awaiting-pair\");\n },\n onMessage: (msg: ISocketMessage) => this.handleMessage(msg),\n onError: () => this.fail(new Error(\"WebSocket connection failed\")),\n });\n\n this.transport.connect(relay);\n await this.emitEntryPoint();\n } catch (err) {\n this.fail(err instanceof Error ? err : new Error(\"Start failed\"));\n }\n }\n\n /**\n * Manually stops the authentication process and closes connections.\n */\n stop() {\n this.terminate(false);\n }\n\n /* -------------------- internals -------------------- */\n\n /** Fetches the WebSocket Relay URL from the backend */\n private async fetchRelayUrl(): Promise<string> {\n const { publicKey, projectId, authType } = this.config;\n const res = await fetch(\n `${BASEURL}/relay?public_key=${publicKey}&auth_type=${authType}&project_id=${projectId}`\n );\n\n if (!res.ok) {\n throw new Error(\"Failed to fetch relay URL\");\n }\n\n const json = await res.json();\n return json.relay_url;\n }\n\n /**\n * Decides whether to show a QR code (Desktop) or a Deep Link (Mobile).\n */\n private async emitEntryPoint() {\n const payload = {\n sessionID: this.sessionId,\n sessionKey: this.sessionKey,\n publicKey: this.config.publicKey,\n authType: this.config.authType,\n projectId: this.config.projectId,\n url: window.location.href,\n };\n\n const shouldUseQR =\n this.config.forceQRCode ||\n !/Android|iPhone|iPad/i.test(navigator.userAgent);\n\n if (!shouldUseQR && this.sessionKey) {\n // For mobile: Store session locally so we can recover when the user returns from the app\n storeAuthSession(this.sessionId, this.sessionKey, 5 * 60_000);\n this.emit(\n \"deeplink\",\n `pelicanvault://auth/deep-link?data=${encodeURIComponent(\n JSON.stringify(payload)\n )}`\n );\n } else {\n // For desktop: Generate a QR code for the mobile app to scan\n const qr = await QRCode.toDataURL(JSON.stringify(payload));\n this.emit(\"qr\", qr);\n }\n }\n\n /** Main WebSocket message router */\n private handleMessage(msg: ISocketMessage) {\n console.log(msg);\n\n switch (msg.type) {\n case \"paired\":\n console.log(\"Paired\");\n\n this.stateMachine.transition(\"paired\");\n this.transport!.send({\n type: \"authenticate\",\n sessionID: this.sessionId,\n ...this.config,\n url: window.location.href,\n });\n return;\n\n case \"phone-auth-success\":\n // Mobile device successfully authenticated and sent encrypted credentials\n this.handleAuthSuccess(msg);\n return;\n\n case \"phone-terminated\":\n this.fail(new Error(\"Authenticating device terminated the connection\"));\n this.restartIfContinuous();\n return;\n\n case \"confirmed\":\n // Handshake complete\n this.terminate(true);\n this.restartIfContinuous();\n return;\n }\n }\n\n /**\n * Decrypts the identity payload received from the phone using the session key.\n */\n private handleAuthSuccess(msg: ISocketMessage) {\n if (!this.sessionKey || !msg.cipher || !msg.nonce) {\n this.fail(new Error(\"Invalid authentication payload\"));\n this.restartIfContinuous();\n return;\n }\n\n try {\n const decrypted = this.crypto.decryptSymmetric({\n encrypted: { cipher: msg.cipher, nonce: msg.nonce },\n keyString: this.sessionKey,\n });\n\n if (!decrypted) {\n this.fail(new Error(\"Invalid authentication data\"));\n this.restartIfContinuous();\n return;\n }\n\n const result: IdentityResult = JSON.parse(decrypted);\n\n this.emit(\"success\", result);\n this.stateMachine.transition(\"authenticated\");\n\n // Signal to the relay/phone that we have received and decrypted the data\n this.transport?.send({\n type: \"confirm\",\n sessionID: this.sessionId,\n });\n } catch {\n this.fail(new Error(\"Failed to decrypt authentication data\"));\n this.restartIfContinuous();\n }\n }\n\n /**\n * Logic to handle users returning to the browser tab after using the mobile app.\n * Checks the server for a completed session that might have finished while in background.\n */\n\n private async getCachedEntry(cached: AuthSession) {\n try {\n const res = await fetch(\n `${BASEURL}/session?session_id=${cached.sessionId}`\n );\n\n if (!res.ok) throw new Error(\"Invalid session\");\n\n const data = await res.json();\n const decrypted = this.crypto.decryptSymmetric({\n encrypted: { cipher: data.cipher, nonce: data.nonce },\n keyString: cached.sessionKey,\n });\n\n if (!decrypted) {\n this.fail(new Error(\"Invalid session data\"));\n this.restartIfContinuous();\n return;\n }\n const result: IdentityResult = JSON.parse(decrypted);\n this.emit(\"success\", result);\n clearAuthSession();\n } catch {\n this.fail(new Error(\"Session recovery failed\"));\n this.restartIfContinuous();\n }\n }\n\n private attachVisibilityRecovery() {\n this.visibilityHandler = async () => {\n if (document.visibilityState !== \"visible\") return;\n\n const cached = getAuthSession();\n if (!cached) return;\n await this.getCachedEntry(cached);\n };\n\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n\n private detachVisibilityRecovery() {\n if (this.visibilityHandler) {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n this.visibilityHandler = undefined;\n }\n }\n\n /** Cleans up the current session state */\n private terminate(success: boolean) {\n if (!this.transport) return;\n if (!success) {\n this.transport?.send({\n type: \"client-terminated\",\n sessionID: this.sessionId,\n projectId: this.config.projectId,\n publicKey: this.config.publicKey,\n authType: this.config.authType,\n });\n }\n\n setTimeout(() => {\n this.transport?.close();\n }, 150);\n\n clearAuthSession();\n this.resetSession();\n\n if (!this.config.continuousMode) {\n this.detachVisibilityRecovery();\n }\n this.stateMachine.transition(success ? \"confirmed\" : \"terminated\");\n }\n\n private restartIfContinuous() {\n if (!this.config.continuousMode) return;\n this.terminate(false);\n this.stateMachine.transition(\"idle\");\n\n setTimeout(() => {\n this.start();\n }, 150);\n }\n\n private resetSession() {\n this.sessionId = \"\";\n this.sessionKey = null;\n }\n\n /** Completely destroys the instance and removes all listeners */\n destroy() {\n this.detachVisibilityRecovery();\n this.transport?.close();\n this.listeners = {};\n }\n\n private emit<K extends keyof PelicanAuthEventMap>(\n event: K,\n payload: PelicanAuthEventMap[K]\n ) {\n this.listeners[event]?.forEach((cb) => cb(payload));\n }\n\n private fail(err: Error) {\n this.emit(\"error\", err);\n this.stateMachine.transition(\"error\");\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.mjs CHANGED
@@ -180,14 +180,47 @@ var StateMachine = class {
180
180
  // src/utilities/transport.ts
181
181
  var Transport = class {
182
182
  constructor(handlers) {
183
+ this.reconnectAttempts = 0;
184
+ this.maxReconnectAttempts = 5;
185
+ this.isExplicitlyClosed = false;
183
186
  this.handlers = handlers;
184
187
  }
185
188
  connect(url) {
189
+ this.url = url;
190
+ this.isExplicitlyClosed = false;
186
191
  this.socket = new WebSocket(url);
187
- this.socket.onopen = () => this.handlers.onOpen?.();
188
- this.socket.onmessage = (e) => this.handlers.onMessage?.(e.data);
189
- this.socket.onerror = (e) => this.handlers.onError?.(e);
190
- this.socket.onclose = (e) => this.handlers.onClose?.(e);
192
+ this.socket.onopen = () => {
193
+ this.reconnectAttempts = 0;
194
+ this.handlers.onOpen?.();
195
+ };
196
+ this.socket.onmessage = (e) => {
197
+ try {
198
+ const data = JSON.parse(e.data);
199
+ this.handlers.onMessage?.(data);
200
+ } catch (err) {
201
+ console.error("Failed to parse message", err);
202
+ }
203
+ };
204
+ this.socket.onerror = (e) => {
205
+ this.handlers.onError?.(e);
206
+ };
207
+ this.socket.onclose = (e) => {
208
+ this.handlers.onClose?.(e);
209
+ if (!this.isExplicitlyClosed) {
210
+ this.attemptReconnect();
211
+ }
212
+ };
213
+ }
214
+ attemptReconnect() {
215
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
216
+ console.error("\u274C Max reconnect attempts reached");
217
+ return;
218
+ }
219
+ this.reconnectAttempts++;
220
+ const delay = Math.pow(2, this.reconnectAttempts) * 500;
221
+ setTimeout(() => {
222
+ if (this.url) this.connect(this.url);
223
+ }, delay);
191
224
  }
192
225
  send(payload) {
193
226
  if (this.socket?.readyState === WebSocket.OPEN) {
@@ -195,6 +228,7 @@ var Transport = class {
195
228
  }
196
229
  }
197
230
  close() {
231
+ this.isExplicitlyClosed = true;
198
232
  this.socket?.close();
199
233
  }
200
234
  };
@@ -303,16 +337,18 @@ var PelicanAuthentication = class {
303
337
  )}`
304
338
  );
305
339
  } else {
306
- const qr = await QRCode.toDataURL(JSON.stringify(payload));
340
+ const qr = await QRCode.toDataURL(JSON.stringify(payload), {
341
+ type: "image/png",
342
+ scale: 3,
343
+ color: { light: "#FFFFF5", dark: "#121212" }
344
+ });
307
345
  this.emit("qr", qr);
308
346
  }
309
347
  }
310
348
  /** Main WebSocket message router */
311
349
  handleMessage(msg) {
312
- console.log(msg);
313
350
  switch (msg.type) {
314
351
  case "paired":
315
- console.log("Paired");
316
352
  this.stateMachine.transition("paired");
317
353
  this.transport.send({
318
354
  type: "authenticate",
@@ -420,20 +456,17 @@ var PelicanAuthentication = class {
420
456
  authType: this.config.authType
421
457
  });
422
458
  }
423
- setTimeout(() => {
424
- this.transport?.close();
425
- }, 150);
459
+ this.transport?.close();
426
460
  clearAuthSession();
427
461
  this.resetSession();
428
462
  if (!this.config.continuousMode) {
429
463
  this.detachVisibilityRecovery();
430
464
  }
431
- this.stateMachine.transition(success ? "confirmed" : "terminated");
465
+ this.stateMachine.transition(success ? "confirmed" : "idle");
432
466
  }
433
467
  restartIfContinuous() {
434
- if (!this.config.continuousMode) return;
435
- this.terminate(false);
436
468
  this.stateMachine.transition("idle");
469
+ if (!this.config.continuousMode) return;
437
470
  setTimeout(() => {
438
471
  this.start();
439
472
  }, 150);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utilities/crypto.ts","../src/utilities/storage.ts","../src/utilities/stateMachine.ts","../src/utilities/transport.ts","../src/constants.ts","../src/engine/engine.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import nacl from \"tweetnacl\";\nimport { decodeBase64, encodeBase64 } from \"tweetnacl-util\";\n\ninterface EncryptedMessage {\n cipher: string; // Base64 encoded\n nonce: string; // Base64 encoded\n}\n\nexport class CryptoService {\n generateSymmetricKey(): string {\n const key = nacl.randomBytes(32);\n return encodeBase64(key);\n }\n\n /**\n * Encrypt with symmetric key (secret-key encryption)\n * Use this when both parties share the same secret key\n * @param plaintext - Message to encrypt\n * @param keyString - Symmetric key (base64)\n * @returns Encrypted message with nonce\n */\n encryptSymmetric({\n plaintext,\n keyString,\n }: {\n plaintext: string;\n keyString: string;\n }): EncryptedMessage {\n const key = decodeBase64(keyString);\n const nonce = nacl.randomBytes(24);\n\n const messageBytes = new TextEncoder().encode(plaintext);\n\n const ciphertext = nacl.secretbox(messageBytes, nonce, key);\n\n return {\n cipher: encodeBase64(ciphertext),\n nonce: encodeBase64(nonce),\n };\n }\n\n /**\n * Decrypt with symmetric key\n * @param encrypted - Encrypted message with nonce\n * @param keyString - Symmetric key (base64)\n * @returns Decrypted plaintext\n */\n decryptSymmetric({\n encrypted,\n keyString,\n }: {\n encrypted: EncryptedMessage;\n keyString: string;\n }): string | null {\n try {\n const key = decodeBase64(keyString);\n const ciphertextBytes = decodeBase64(encrypted.cipher);\n const nonceBytes = decodeBase64(encrypted.nonce);\n\n const decrypted = nacl.secretbox.open(ciphertextBytes, nonceBytes, key);\n\n if (!decrypted) {\n throw new Error(\"Decryption failed - invalid key or corrupted data\");\n }\n\n const decoded = new TextDecoder().decode(decrypted);\n return decoded;\n } catch (error) {\n console.error(\"Decryption failed\", error);\n return null;\n }\n }\n}\n\nexport default CryptoService;\nexport type { EncryptedMessage };\n","// hybridStorage.ts\n/**\n * Hybrid storage: Try sessionStorage first, fallback to memory\n * Best of both worlds - survives page refresh but auto-cleans\n */\n\ninterface StorageOptions {\n ttlMs?: number;\n useSessionStorage?: boolean;\n}\n\nclass AuthStorage {\n private readonly prefix = \"pelican_auth_\";\n private readonly defaultTTL = 5 * 60 * 1000; // 5 minutes\n private memoryCache: Map<string, { value: any; expiresAt: number }> =\n new Map();\n\n /**\n * Store auth session with automatic cleanup\n */\n set(key: string, value: any, options: StorageOptions = {}): void {\n const { ttlMs = this.defaultTTL, useSessionStorage = true } = options;\n\n const expiresAt = Date.now() + ttlMs;\n const data = { value, expiresAt };\n\n // Try sessionStorage first\n if (useSessionStorage) {\n try {\n sessionStorage.setItem(`${this.prefix}${key}`, JSON.stringify(data));\n } catch (error) {\n console.warn(\"SessionStorage unavailable, using memory:\", error);\n this.setMemory(key, data);\n }\n } else {\n this.setMemory(key, data);\n }\n }\n\n /**\n * Get stored value if not expired\n */\n get(key: string): any | null {\n // Try sessionStorage first\n try {\n const stored = sessionStorage.getItem(`${this.prefix}${key}`);\n if (stored) {\n const data = JSON.parse(stored);\n\n // Check expiration\n if (Date.now() > data.expiresAt) {\n this.remove(key);\n return null;\n }\n\n return data.value;\n }\n } catch (error) {\n // Fallback to memory\n }\n\n // Try memory cache\n return this.getMemory(key);\n }\n\n /**\n * Remove specific key\n */\n remove(key: string): void {\n try {\n sessionStorage.removeItem(`${this.prefix}${key}`);\n } catch (error) {\n // Ignore\n }\n this.memoryCache.delete(key);\n }\n\n /**\n * Clear all auth data\n */\n clear(): void {\n // Clear sessionStorage\n try {\n Object.keys(sessionStorage).forEach((key) => {\n if (key.startsWith(this.prefix)) {\n sessionStorage.removeItem(key);\n }\n });\n } catch (error) {\n // Ignore\n }\n\n // Clear memory\n this.memoryCache.clear();\n }\n\n // ========================================\n // Memory cache helpers\n // ========================================\n\n private setMemory(\n key: string,\n data: { value: any; expiresAt: number }\n ): void {\n this.memoryCache.set(key, data);\n\n // Schedule cleanup\n const ttl = data.expiresAt - Date.now();\n setTimeout(() => {\n this.memoryCache.delete(key);\n }, ttl);\n }\n\n private getMemory(key: string): any | null {\n const data = this.memoryCache.get(key);\n if (!data) return null;\n\n if (Date.now() > data.expiresAt) {\n this.memoryCache.delete(key);\n return null;\n }\n\n return data.value;\n }\n}\n\n// Singleton instance\nconst storage = new AuthStorage();\n\n// ========================================\n// Convenience functions for auth flow\n// ========================================\n\nexport interface AuthSession {\n sessionId: string;\n sessionKey: string;\n}\n\nexport const storeAuthSession = (\n sessionId: string,\n sessionKey: string,\n ttlMs?: number\n): void => {\n storage.set(\"session\", { sessionId, sessionKey }, { ttlMs });\n};\n\nexport const getAuthSession = (): AuthSession | null => {\n return storage.get(\"session\");\n};\n\nexport const clearAuthSession = (): void => {\n storage.remove(\"session\");\n};\n\nexport const clearAllAuthData = (): void => {\n storage.clear();\n};\n\nexport default storage;\n","import type { PelicanAuthState } from \"../types/types\";\n\nexport class StateMachine {\n private state: PelicanAuthState = \"idle\";\n private listeners = new Set<(s: PelicanAuthState) => void>();\n\n get current() {\n return this.state;\n }\n\n transition(next: PelicanAuthState) {\n this.state = next;\n this.listeners.forEach((l) => l(next));\n }\n\n subscribe(fn: (s: PelicanAuthState) => void) {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n}\n","import { ISocketMessage } from \"../types/types\";\n\ntype TransportHandlers = {\n onOpen?: () => void;\n onMessage?: (msg: ISocketMessage) => void;\n onError?: (err: Event) => void;\n onClose?: (ev: CloseEvent) => void;\n};\n\ninterface PelicanMessageEvent extends MessageEvent {\n data: ISocketMessage;\n}\nexport class Transport {\n private socket?: WebSocket;\n private handlers: TransportHandlers;\n\n constructor(handlers: TransportHandlers) {\n this.handlers = handlers;\n }\n\n connect(url: string) {\n this.socket = new WebSocket(url);\n\n this.socket.onopen = () => this.handlers.onOpen?.();\n this.socket.onmessage = (e: PelicanMessageEvent) =>\n this.handlers.onMessage?.(e.data);\n this.socket.onerror = (e: Event) => this.handlers.onError?.(e);\n this.socket.onclose = (e: CloseEvent) => this.handlers.onClose?.(e);\n }\n\n send(payload: ISocketMessage) {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify(payload));\n }\n }\n\n close() {\n this.socket?.close();\n }\n}\n","export const BASEURL = \"http://localhost:8080\";\n","import CryptoService from \"../utilities/crypto\";\nimport QRCode from \"qrcode\";\nimport {\n PelicanAuthConfig,\n PelicanAuthEventMap,\n ISocketMessage,\n IdentityResult,\n} from \"../types/types\";\nimport {\n storeAuthSession,\n getAuthSession,\n clearAuthSession,\n AuthSession,\n} from \"../utilities/storage\";\nimport { StateMachine } from \"../utilities/stateMachine\";\nimport { Transport } from \"../utilities/transport\";\n\nimport { BASEURL } from \"../constants\";\n\ntype Listener<T> = (payload: T) => void;\n\n/**\n * PelicanAuth SDK\n * Handles cross-device authentication via WebSockets and E2EE (End-to-End Encryption).\n */\nexport class PelicanAuthentication {\n private readonly crypto = new CryptoService();\n private readonly stateMachine = new StateMachine();\n\n private transport?: Transport;\n private sessionId = \"\";\n private sessionKey: string | null = null;\n\n private visibilityHandler?: () => void;\n\n private listeners: {\n [K in keyof PelicanAuthEventMap]?: Set<Listener<any>>;\n } = {};\n\n private readonly config: Required<PelicanAuthConfig>;\n\n constructor(config: PelicanAuthConfig) {\n if (!config.publicKey) throw new Error(\"Missing publicKey\");\n if (!config.projectId) throw new Error(\"Missing projectId\");\n if (!config.authType) throw new Error(\"Missing authType\");\n\n this.config = {\n continuousMode: false,\n forceQRCode: false,\n ...config,\n };\n\n // Sync internal state machine changes with the 'state' event\n this.stateMachine.subscribe((s) => this.emit(\"state\", s));\n this.attachVisibilityRecovery();\n }\n\n /* -------------------- public API -------------------- */\n\n /**\n * Subscribe to SDK events (qr, deeplink, success, error, state)\n * @returns Unsubscribe function\n */\n on<K extends keyof PelicanAuthEventMap>(\n event: K,\n cb: Listener<PelicanAuthEventMap[K]>\n ) {\n this.listeners[event] ??= new Set();\n this.listeners[event]!.add(cb);\n return () => this.listeners[event]!.delete(cb);\n }\n\n /**\n * Initializes the authentication flow.\n * Fetches a relay, establishes a WebSocket, and generates the E2EE session key.\n */\n async start() {\n if (this.stateMachine.current !== \"idle\") return;\n\n this.resetSession();\n this.stateMachine.transition(\"initializing\");\n\n try {\n const relay = await this.fetchRelayUrl();\n\n // Generate a fresh symmetric key for this specific session\n this.sessionKey = this.crypto.generateSymmetricKey();\n this.sessionId = crypto.randomUUID() + crypto.randomUUID();\n\n this.transport = new Transport({\n onOpen: () => {\n // Register this browser session with the relay\n this.transport!.send({\n type: \"register\",\n sessionID: this.sessionId,\n ...this.config,\n });\n this.stateMachine.transition(\"awaiting-pair\");\n },\n onMessage: (msg: ISocketMessage) => this.handleMessage(msg),\n onError: () => this.fail(new Error(\"WebSocket connection failed\")),\n });\n\n this.transport.connect(relay);\n await this.emitEntryPoint();\n } catch (err) {\n this.fail(err instanceof Error ? err : new Error(\"Start failed\"));\n }\n }\n\n /**\n * Manually stops the authentication process and closes connections.\n */\n stop() {\n this.terminate(false);\n }\n\n /* -------------------- internals -------------------- */\n\n /** Fetches the WebSocket Relay URL from the backend */\n private async fetchRelayUrl(): Promise<string> {\n const { publicKey, projectId, authType } = this.config;\n const res = await fetch(\n `${BASEURL}/relay?public_key=${publicKey}&auth_type=${authType}&project_id=${projectId}`\n );\n\n if (!res.ok) {\n throw new Error(\"Failed to fetch relay URL\");\n }\n\n const json = await res.json();\n return json.relay_url;\n }\n\n /**\n * Decides whether to show a QR code (Desktop) or a Deep Link (Mobile).\n */\n private async emitEntryPoint() {\n const payload = {\n sessionID: this.sessionId,\n sessionKey: this.sessionKey,\n publicKey: this.config.publicKey,\n authType: this.config.authType,\n projectId: this.config.projectId,\n url: window.location.href,\n };\n\n const shouldUseQR =\n this.config.forceQRCode ||\n !/Android|iPhone|iPad/i.test(navigator.userAgent);\n\n if (!shouldUseQR && this.sessionKey) {\n // For mobile: Store session locally so we can recover when the user returns from the app\n storeAuthSession(this.sessionId, this.sessionKey, 5 * 60_000);\n this.emit(\n \"deeplink\",\n `pelicanvault://auth/deep-link?data=${encodeURIComponent(\n JSON.stringify(payload)\n )}`\n );\n } else {\n // For desktop: Generate a QR code for the mobile app to scan\n const qr = await QRCode.toDataURL(JSON.stringify(payload));\n this.emit(\"qr\", qr);\n }\n }\n\n /** Main WebSocket message router */\n private handleMessage(msg: ISocketMessage) {\n console.log(msg);\n\n switch (msg.type) {\n case \"paired\":\n console.log(\"Paired\");\n\n this.stateMachine.transition(\"paired\");\n this.transport!.send({\n type: \"authenticate\",\n sessionID: this.sessionId,\n ...this.config,\n url: window.location.href,\n });\n return;\n\n case \"phone-auth-success\":\n // Mobile device successfully authenticated and sent encrypted credentials\n this.handleAuthSuccess(msg);\n return;\n\n case \"phone-terminated\":\n this.fail(new Error(\"Authenticating device terminated the connection\"));\n this.restartIfContinuous();\n return;\n\n case \"confirmed\":\n // Handshake complete\n this.terminate(true);\n this.restartIfContinuous();\n return;\n }\n }\n\n /**\n * Decrypts the identity payload received from the phone using the session key.\n */\n private handleAuthSuccess(msg: ISocketMessage) {\n if (!this.sessionKey || !msg.cipher || !msg.nonce) {\n this.fail(new Error(\"Invalid authentication payload\"));\n this.restartIfContinuous();\n return;\n }\n\n try {\n const decrypted = this.crypto.decryptSymmetric({\n encrypted: { cipher: msg.cipher, nonce: msg.nonce },\n keyString: this.sessionKey,\n });\n\n if (!decrypted) {\n this.fail(new Error(\"Invalid authentication data\"));\n this.restartIfContinuous();\n return;\n }\n\n const result: IdentityResult = JSON.parse(decrypted);\n\n this.emit(\"success\", result);\n this.stateMachine.transition(\"authenticated\");\n\n // Signal to the relay/phone that we have received and decrypted the data\n this.transport?.send({\n type: \"confirm\",\n sessionID: this.sessionId,\n });\n } catch {\n this.fail(new Error(\"Failed to decrypt authentication data\"));\n this.restartIfContinuous();\n }\n }\n\n /**\n * Logic to handle users returning to the browser tab after using the mobile app.\n * Checks the server for a completed session that might have finished while in background.\n */\n\n private async getCachedEntry(cached: AuthSession) {\n try {\n const res = await fetch(\n `${BASEURL}/session?session_id=${cached.sessionId}`\n );\n\n if (!res.ok) throw new Error(\"Invalid session\");\n\n const data = await res.json();\n const decrypted = this.crypto.decryptSymmetric({\n encrypted: { cipher: data.cipher, nonce: data.nonce },\n keyString: cached.sessionKey,\n });\n\n if (!decrypted) {\n this.fail(new Error(\"Invalid session data\"));\n this.restartIfContinuous();\n return;\n }\n const result: IdentityResult = JSON.parse(decrypted);\n this.emit(\"success\", result);\n clearAuthSession();\n } catch {\n this.fail(new Error(\"Session recovery failed\"));\n this.restartIfContinuous();\n }\n }\n\n private attachVisibilityRecovery() {\n this.visibilityHandler = async () => {\n if (document.visibilityState !== \"visible\") return;\n\n const cached = getAuthSession();\n if (!cached) return;\n await this.getCachedEntry(cached);\n };\n\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n\n private detachVisibilityRecovery() {\n if (this.visibilityHandler) {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n this.visibilityHandler = undefined;\n }\n }\n\n /** Cleans up the current session state */\n private terminate(success: boolean) {\n if (!this.transport) return;\n if (!success) {\n this.transport?.send({\n type: \"client-terminated\",\n sessionID: this.sessionId,\n projectId: this.config.projectId,\n publicKey: this.config.publicKey,\n authType: this.config.authType,\n });\n }\n\n setTimeout(() => {\n this.transport?.close();\n }, 150);\n\n clearAuthSession();\n this.resetSession();\n\n if (!this.config.continuousMode) {\n this.detachVisibilityRecovery();\n }\n this.stateMachine.transition(success ? \"confirmed\" : \"terminated\");\n }\n\n private restartIfContinuous() {\n if (!this.config.continuousMode) return;\n this.terminate(false);\n this.stateMachine.transition(\"idle\");\n\n setTimeout(() => {\n this.start();\n }, 150);\n }\n\n private resetSession() {\n this.sessionId = \"\";\n this.sessionKey = null;\n }\n\n /** Completely destroys the instance and removes all listeners */\n destroy() {\n this.detachVisibilityRecovery();\n this.transport?.close();\n this.listeners = {};\n }\n\n private emit<K extends keyof PelicanAuthEventMap>(\n event: K,\n payload: PelicanAuthEventMap[K]\n ) {\n this.listeners[event]?.forEach((cb) => cb(payload));\n }\n\n private fail(err: Error) {\n this.emit(\"error\", err);\n this.stateMachine.transition(\"error\");\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/utilities/crypto.ts","../src/utilities/storage.ts","../src/utilities/stateMachine.ts","../src/utilities/transport.ts","../src/constants.ts","../src/engine/engine.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import nacl from \"tweetnacl\";\nimport { decodeBase64, encodeBase64 } from \"tweetnacl-util\";\n\ninterface EncryptedMessage {\n cipher: string; // Base64 encoded\n nonce: string; // Base64 encoded\n}\n\nexport class CryptoService {\n generateSymmetricKey(): string {\n const key = nacl.randomBytes(32);\n return encodeBase64(key);\n }\n\n /**\n * Encrypt with symmetric key (secret-key encryption)\n * Use this when both parties share the same secret key\n * @param plaintext - Message to encrypt\n * @param keyString - Symmetric key (base64)\n * @returns Encrypted message with nonce\n */\n encryptSymmetric({\n plaintext,\n keyString,\n }: {\n plaintext: string;\n keyString: string;\n }): EncryptedMessage {\n const key = decodeBase64(keyString);\n const nonce = nacl.randomBytes(24);\n\n const messageBytes = new TextEncoder().encode(plaintext);\n\n const ciphertext = nacl.secretbox(messageBytes, nonce, key);\n\n return {\n cipher: encodeBase64(ciphertext),\n nonce: encodeBase64(nonce),\n };\n }\n\n /**\n * Decrypt with symmetric key\n * @param encrypted - Encrypted message with nonce\n * @param keyString - Symmetric key (base64)\n * @returns Decrypted plaintext\n */\n decryptSymmetric({\n encrypted,\n keyString,\n }: {\n encrypted: EncryptedMessage;\n keyString: string;\n }): string | null {\n try {\n const key = decodeBase64(keyString);\n const ciphertextBytes = decodeBase64(encrypted.cipher);\n const nonceBytes = decodeBase64(encrypted.nonce);\n\n const decrypted = nacl.secretbox.open(ciphertextBytes, nonceBytes, key);\n\n if (!decrypted) {\n throw new Error(\"Decryption failed - invalid key or corrupted data\");\n }\n\n const decoded = new TextDecoder().decode(decrypted);\n return decoded;\n } catch (error) {\n console.error(\"Decryption failed\", error);\n return null;\n }\n }\n}\n\nexport default CryptoService;\nexport type { EncryptedMessage };\n","// hybridStorage.ts\n/**\n * Hybrid storage: Try sessionStorage first, fallback to memory\n * Best of both worlds - survives page refresh but auto-cleans\n */\n\ninterface StorageOptions {\n ttlMs?: number;\n useSessionStorage?: boolean;\n}\n\nclass AuthStorage {\n private readonly prefix = \"pelican_auth_\";\n private readonly defaultTTL = 5 * 60 * 1000; // 5 minutes\n private memoryCache: Map<string, { value: any; expiresAt: number }> =\n new Map();\n\n /**\n * Store auth session with automatic cleanup\n */\n set(key: string, value: any, options: StorageOptions = {}): void {\n const { ttlMs = this.defaultTTL, useSessionStorage = true } = options;\n\n const expiresAt = Date.now() + ttlMs;\n const data = { value, expiresAt };\n\n // Try sessionStorage first\n if (useSessionStorage) {\n try {\n sessionStorage.setItem(`${this.prefix}${key}`, JSON.stringify(data));\n } catch (error) {\n console.warn(\"SessionStorage unavailable, using memory:\", error);\n this.setMemory(key, data);\n }\n } else {\n this.setMemory(key, data);\n }\n }\n\n /**\n * Get stored value if not expired\n */\n get(key: string): any | null {\n // Try sessionStorage first\n try {\n const stored = sessionStorage.getItem(`${this.prefix}${key}`);\n if (stored) {\n const data = JSON.parse(stored);\n\n // Check expiration\n if (Date.now() > data.expiresAt) {\n this.remove(key);\n return null;\n }\n\n return data.value;\n }\n } catch (error) {\n // Fallback to memory\n }\n\n // Try memory cache\n return this.getMemory(key);\n }\n\n /**\n * Remove specific key\n */\n remove(key: string): void {\n try {\n sessionStorage.removeItem(`${this.prefix}${key}`);\n } catch (error) {\n // Ignore\n }\n this.memoryCache.delete(key);\n }\n\n /**\n * Clear all auth data\n */\n clear(): void {\n // Clear sessionStorage\n try {\n Object.keys(sessionStorage).forEach((key) => {\n if (key.startsWith(this.prefix)) {\n sessionStorage.removeItem(key);\n }\n });\n } catch (error) {\n // Ignore\n }\n\n // Clear memory\n this.memoryCache.clear();\n }\n\n // ========================================\n // Memory cache helpers\n // ========================================\n\n private setMemory(\n key: string,\n data: { value: any; expiresAt: number }\n ): void {\n this.memoryCache.set(key, data);\n\n // Schedule cleanup\n const ttl = data.expiresAt - Date.now();\n setTimeout(() => {\n this.memoryCache.delete(key);\n }, ttl);\n }\n\n private getMemory(key: string): any | null {\n const data = this.memoryCache.get(key);\n if (!data) return null;\n\n if (Date.now() > data.expiresAt) {\n this.memoryCache.delete(key);\n return null;\n }\n\n return data.value;\n }\n}\n\n// Singleton instance\nconst storage = new AuthStorage();\n\n// ========================================\n// Convenience functions for auth flow\n// ========================================\n\nexport interface AuthSession {\n sessionId: string;\n sessionKey: string;\n}\n\nexport const storeAuthSession = (\n sessionId: string,\n sessionKey: string,\n ttlMs?: number\n): void => {\n storage.set(\"session\", { sessionId, sessionKey }, { ttlMs });\n};\n\nexport const getAuthSession = (): AuthSession | null => {\n return storage.get(\"session\");\n};\n\nexport const clearAuthSession = (): void => {\n storage.remove(\"session\");\n};\n\nexport const clearAllAuthData = (): void => {\n storage.clear();\n};\n\nexport default storage;\n","import type { PelicanAuthState } from \"../types/types\";\n\nexport class StateMachine {\n private state: PelicanAuthState = \"idle\";\n private listeners = new Set<(s: PelicanAuthState) => void>();\n\n get current() {\n return this.state;\n }\n\n transition(next: PelicanAuthState) {\n this.state = next;\n this.listeners.forEach((l) => l(next));\n }\n\n subscribe(fn: (s: PelicanAuthState) => void) {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n}\n","import { ISocketMessage } from \"../types/types\";\n\ntype TransportHandlers = {\n onOpen?: () => void;\n onMessage?: (msg: ISocketMessage) => void;\n onError?: (err: Event) => void;\n onClose?: (ev: CloseEvent) => void;\n};\n\nexport class Transport {\n private socket?: WebSocket;\n private handlers: TransportHandlers;\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n private isExplicitlyClosed = false;\n private url?: string;\n\n constructor(handlers: TransportHandlers) {\n this.handlers = handlers;\n }\n\n connect(url: string) {\n this.url = url;\n this.isExplicitlyClosed = false;\n this.socket = new WebSocket(url);\n\n this.socket.onopen = () => {\n this.reconnectAttempts = 0;\n this.handlers.onOpen?.();\n };\n this.socket.onmessage = (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data);\n this.handlers.onMessage?.(data);\n } catch (err) {\n console.error(\"Failed to parse message\", err);\n }\n };\n this.socket.onerror = (e: Event) => {\n this.handlers.onError?.(e);\n };\n this.socket.onclose = (e: CloseEvent) => {\n this.handlers.onClose?.(e);\n\n // Only reconnect if the user didn't call .close() manually\n if (!this.isExplicitlyClosed) {\n this.attemptReconnect();\n }\n };\n }\n\n private attemptReconnect() {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n console.error(\"❌ Max reconnect attempts reached\");\n return;\n }\n\n this.reconnectAttempts++;\n\n const delay = Math.pow(2, this.reconnectAttempts) * 500;\n setTimeout(() => {\n if (this.url) this.connect(this.url);\n }, delay);\n }\n send(payload: ISocketMessage) {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify(payload));\n }\n }\n\n close() {\n this.isExplicitlyClosed = true;\n this.socket?.close();\n }\n}\n","export const BASEURL = \"http://localhost:8080\";\n","import CryptoService from \"../utilities/crypto\";\nimport QRCode from \"qrcode\";\nimport {\n PelicanAuthConfig,\n PelicanAuthEventMap,\n ISocketMessage,\n IdentityResult,\n} from \"../types/types\";\nimport {\n storeAuthSession,\n getAuthSession,\n clearAuthSession,\n AuthSession,\n} from \"../utilities/storage\";\nimport { StateMachine } from \"../utilities/stateMachine\";\nimport { Transport } from \"../utilities/transport\";\n\nimport { BASEURL } from \"../constants\";\n\ntype Listener<T> = (payload: T) => void;\n\n/**\n * PelicanAuth SDK\n * Handles cross-device authentication via WebSockets and E2EE (End-to-End Encryption).\n */\nexport class PelicanAuthentication {\n private readonly crypto = new CryptoService();\n private readonly stateMachine = new StateMachine();\n\n private transport?: Transport;\n private sessionId = \"\";\n private sessionKey: string | null = null;\n\n private visibilityHandler?: () => void;\n\n private listeners: {\n [K in keyof PelicanAuthEventMap]?: Set<Listener<any>>;\n } = {};\n\n private readonly config: Required<PelicanAuthConfig>;\n\n constructor(config: PelicanAuthConfig) {\n if (!config.publicKey) throw new Error(\"Missing publicKey\");\n if (!config.projectId) throw new Error(\"Missing projectId\");\n if (!config.authType) throw new Error(\"Missing authType\");\n\n this.config = {\n continuousMode: false,\n forceQRCode: false,\n ...config,\n };\n\n // Sync internal state machine changes with the 'state' event\n this.stateMachine.subscribe((s) => this.emit(\"state\", s));\n this.attachVisibilityRecovery();\n }\n\n /* -------------------- public API -------------------- */\n\n /**\n * Subscribe to SDK events (qr, deeplink, success, error, state)\n * @returns Unsubscribe function\n */\n on<K extends keyof PelicanAuthEventMap>(\n event: K,\n cb: Listener<PelicanAuthEventMap[K]>\n ) {\n this.listeners[event] ??= new Set();\n this.listeners[event]!.add(cb);\n return () => this.listeners[event]!.delete(cb);\n }\n\n /**\n * Initializes the authentication flow.\n * Fetches a relay, establishes a WebSocket, and generates the E2EE session key.\n */\n async start() {\n if (this.stateMachine.current !== \"idle\") return;\n\n this.resetSession();\n this.stateMachine.transition(\"initializing\");\n\n try {\n const relay = await this.fetchRelayUrl();\n\n // Generate a fresh symmetric key for this specific session\n this.sessionKey = this.crypto.generateSymmetricKey();\n this.sessionId = crypto.randomUUID() + crypto.randomUUID();\n\n this.transport = new Transport({\n onOpen: () => {\n // Register this browser session with the relay\n this.transport!.send({\n type: \"register\",\n sessionID: this.sessionId,\n ...this.config,\n });\n this.stateMachine.transition(\"awaiting-pair\");\n },\n onMessage: (msg: ISocketMessage) => this.handleMessage(msg),\n onError: () => this.fail(new Error(\"WebSocket connection failed\")),\n });\n\n this.transport.connect(relay);\n await this.emitEntryPoint();\n } catch (err) {\n this.fail(err instanceof Error ? err : new Error(\"Start failed\"));\n }\n }\n\n /**\n * Manually stops the authentication process and closes connections.\n */\n stop() {\n this.terminate(false);\n }\n\n /* -------------------- internals -------------------- */\n\n /** Fetches the WebSocket Relay URL from the backend */\n private async fetchRelayUrl(): Promise<string> {\n const { publicKey, projectId, authType } = this.config;\n const res = await fetch(\n `${BASEURL}/relay?public_key=${publicKey}&auth_type=${authType}&project_id=${projectId}`\n );\n\n if (!res.ok) {\n throw new Error(\"Failed to fetch relay URL\");\n }\n\n const json = await res.json();\n return json.relay_url;\n }\n\n /**\n * Decides whether to show a QR code (Desktop) or a Deep Link (Mobile).\n */\n private async emitEntryPoint() {\n const payload = {\n sessionID: this.sessionId,\n sessionKey: this.sessionKey,\n publicKey: this.config.publicKey,\n authType: this.config.authType,\n projectId: this.config.projectId,\n url: window.location.href,\n };\n\n const shouldUseQR =\n this.config.forceQRCode ||\n !/Android|iPhone|iPad/i.test(navigator.userAgent);\n\n if (!shouldUseQR && this.sessionKey) {\n // For mobile: Store session locally so we can recover when the user returns from the app\n storeAuthSession(this.sessionId, this.sessionKey, 5 * 60_000);\n this.emit(\n \"deeplink\",\n `pelicanvault://auth/deep-link?data=${encodeURIComponent(\n JSON.stringify(payload)\n )}`\n );\n } else {\n const qr = await QRCode.toDataURL(JSON.stringify(payload), {\n type: \"image/png\",\n scale: 3,\n color: { light: \"#FFFFF5\", dark: \"#121212\" },\n });\n this.emit(\"qr\", qr);\n }\n }\n\n /** Main WebSocket message router */\n private handleMessage(msg: ISocketMessage) {\n switch (msg.type) {\n case \"paired\":\n this.stateMachine.transition(\"paired\");\n this.transport!.send({\n type: \"authenticate\",\n sessionID: this.sessionId,\n ...this.config,\n url: window.location.href,\n });\n return;\n\n case \"phone-auth-success\":\n // Mobile device successfully authenticated and sent encrypted credentials\n this.handleAuthSuccess(msg);\n return;\n\n case \"phone-terminated\":\n this.fail(new Error(\"Authenticating device terminated the connection\"));\n this.restartIfContinuous();\n return;\n\n case \"confirmed\":\n // Handshake complete\n this.terminate(true);\n this.restartIfContinuous();\n return;\n }\n }\n\n /**\n * Decrypts the identity payload received from the phone using the session key.\n */\n private handleAuthSuccess(msg: ISocketMessage) {\n if (!this.sessionKey || !msg.cipher || !msg.nonce) {\n this.fail(new Error(\"Invalid authentication payload\"));\n this.restartIfContinuous();\n return;\n }\n\n try {\n const decrypted = this.crypto.decryptSymmetric({\n encrypted: { cipher: msg.cipher, nonce: msg.nonce },\n keyString: this.sessionKey,\n });\n\n if (!decrypted) {\n this.fail(new Error(\"Invalid authentication data\"));\n this.restartIfContinuous();\n return;\n }\n\n const result: IdentityResult = JSON.parse(decrypted);\n\n this.emit(\"success\", result);\n this.stateMachine.transition(\"authenticated\");\n\n // Signal to the relay/phone that we have received and decrypted the data\n this.transport?.send({\n type: \"confirm\",\n sessionID: this.sessionId,\n });\n } catch {\n this.fail(new Error(\"Failed to decrypt authentication data\"));\n this.restartIfContinuous();\n }\n }\n\n /**\n * Logic to handle users returning to the browser tab after using the mobile app.\n * Checks the server for a completed session that might have finished while in background.\n */\n\n private async getCachedEntry(cached: AuthSession) {\n try {\n const res = await fetch(\n `${BASEURL}/session?session_id=${cached.sessionId}`\n );\n\n if (!res.ok) throw new Error(\"Invalid session\");\n\n const data = await res.json();\n const decrypted = this.crypto.decryptSymmetric({\n encrypted: { cipher: data.cipher, nonce: data.nonce },\n keyString: cached.sessionKey,\n });\n\n if (!decrypted) {\n this.fail(new Error(\"Invalid session data\"));\n this.restartIfContinuous();\n return;\n }\n const result: IdentityResult = JSON.parse(decrypted);\n this.emit(\"success\", result);\n clearAuthSession();\n } catch {\n this.fail(new Error(\"Session recovery failed\"));\n this.restartIfContinuous();\n }\n }\n\n private attachVisibilityRecovery() {\n this.visibilityHandler = async () => {\n if (document.visibilityState !== \"visible\") return;\n\n const cached = getAuthSession();\n if (!cached) return;\n await this.getCachedEntry(cached);\n };\n\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n\n private detachVisibilityRecovery() {\n if (this.visibilityHandler) {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n this.visibilityHandler = undefined;\n }\n }\n\n /** Cleans up the current session state */\n private terminate(success: boolean) {\n if (!this.transport) return;\n if (!success) {\n this.transport?.send({\n type: \"client-terminated\",\n sessionID: this.sessionId,\n projectId: this.config.projectId,\n publicKey: this.config.publicKey,\n authType: this.config.authType,\n });\n }\n\n this.transport?.close();\n clearAuthSession();\n this.resetSession();\n\n if (!this.config.continuousMode) {\n this.detachVisibilityRecovery();\n }\n this.stateMachine.transition(success ? \"confirmed\" : \"idle\");\n }\n\n private restartIfContinuous() {\n this.stateMachine.transition(\"idle\");\n if (!this.config.continuousMode) return;\n setTimeout(() => {\n this.start();\n }, 150);\n }\n\n private resetSession() {\n this.sessionId = \"\";\n this.sessionKey = null;\n }\n\n /** Completely destroys the instance and removes all listeners */\n destroy() {\n this.detachVisibilityRecovery();\n this.transport?.close();\n this.listeners = {};\n }\n\n private emit<K extends keyof PelicanAuthEventMap>(\n event: K,\n payload: PelicanAuthEventMap[K]\n ) {\n this.listeners[event]?.forEach((cb) => cb(payload));\n }\n\n private fail(err: Error) {\n this.emit(\"error\", err);\n this.stateMachine.transition(\"error\");\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/utilities/crypto.ts"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAa;IACxB,oBAAoB,IAAI,MAAM;IAY9B,gBAAgB,CAAC,EACf,SAAS,EACT,SAAS,GACV,EAAE;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,gBAAgB;IAoBpB,gBAAgB,CAAC,EACf,SAAS,EACT,SAAS,GACV,EAAE;QACD,SAAS,EAAE,gBAAgB,CAAC;QAC5B,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,MAAM,GAAG,IAAI;CAmBlB;AAED,eAAe,aAAa,CAAC;AAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,37 @@
1
+ import nacl from "tweetnacl";
2
+ import { decodeBase64, encodeBase64 } from "tweetnacl-util";
3
+ export class CryptoService {
4
+ generateSymmetricKey() {
5
+ const key = nacl.randomBytes(32);
6
+ return encodeBase64(key);
7
+ }
8
+ encryptSymmetric({ plaintext, keyString, }) {
9
+ const key = decodeBase64(keyString);
10
+ const nonce = nacl.randomBytes(24);
11
+ const messageBytes = new TextEncoder().encode(plaintext);
12
+ const ciphertext = nacl.secretbox(messageBytes, nonce, key);
13
+ return {
14
+ cipher: encodeBase64(ciphertext),
15
+ nonce: encodeBase64(nonce),
16
+ };
17
+ }
18
+ decryptSymmetric({ encrypted, keyString, }) {
19
+ try {
20
+ const key = decodeBase64(keyString);
21
+ const ciphertextBytes = decodeBase64(encrypted.cipher);
22
+ const nonceBytes = decodeBase64(encrypted.nonce);
23
+ const decrypted = nacl.secretbox.open(ciphertextBytes, nonceBytes, key);
24
+ if (!decrypted) {
25
+ throw new Error("Decryption failed - invalid key or corrupted data");
26
+ }
27
+ const decoded = new TextDecoder().decode(decrypted);
28
+ return decoded;
29
+ }
30
+ catch (error) {
31
+ console.error("Decryption failed", error);
32
+ return null;
33
+ }
34
+ }
35
+ }
36
+ export default CryptoService;
37
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/utilities/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO5D,MAAM,OAAO,aAAa;IACxB,oBAAoB;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACjC,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IASD,gBAAgB,CAAC,EACf,SAAS,EACT,SAAS,GAIV;QACC,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAEnC,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAEzD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAE5D,OAAO;YACL,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC;YAChC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC;SAC3B,CAAC;IACJ,CAAC;IAQD,gBAAgB,CAAC,EACf,SAAS,EACT,SAAS,GAIV;QACC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YACpC,MAAM,eAAe,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACvD,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAEjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;YAExE,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACvE,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACpD,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateMachine.d.ts","sourceRoot":"","sources":["../../src/utilities/stateMachine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,SAAS,CAA4C;IAE7D,IAAI,OAAO,qBAEV;IAED,UAAU,CAAC,IAAI,EAAE,gBAAgB;IAKjC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,IAAI;CAI5C"}
@@ -0,0 +1,18 @@
1
+ export class StateMachine {
2
+ constructor() {
3
+ this.state = "idle";
4
+ this.listeners = new Set();
5
+ }
6
+ get current() {
7
+ return this.state;
8
+ }
9
+ transition(next) {
10
+ this.state = next;
11
+ this.listeners.forEach((l) => l(next));
12
+ }
13
+ subscribe(fn) {
14
+ this.listeners.add(fn);
15
+ return () => this.listeners.delete(fn);
16
+ }
17
+ }
18
+ //# sourceMappingURL=stateMachine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateMachine.js","sourceRoot":"","sources":["../../src/utilities/stateMachine.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,YAAY;IAAzB;QACU,UAAK,GAAqB,MAAM,CAAC;QACjC,cAAS,GAAG,IAAI,GAAG,EAAiC,CAAC;IAe/D,CAAC;IAbC,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,UAAU,CAAC,IAAsB;QAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,SAAS,CAAC,EAAiC;QACzC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;CACF"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/utilities/storage.ts"],"names":[],"mappings":"AAMA,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,cAAM,WAAW;IACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAC5C,OAAO,CAAC,WAAW,CACP;IAKZ,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,GAAE,cAAmB,GAAG,IAAI;IAsBhE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI;IA0B5B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAYzB,KAAK,IAAI,IAAI;IAoBb,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,SAAS;CAWlB;AAGD,QAAA,MAAM,OAAO,aAAoB,CAAC;AAMlC,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,gBAAgB,GAC3B,WAAW,MAAM,EACjB,YAAY,MAAM,EAClB,QAAQ,MAAM,KACb,IAEF,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,WAAW,GAAG,IAE/C,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,IAEnC,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,IAEnC,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -0,0 +1,92 @@
1
+ class AuthStorage {
2
+ constructor() {
3
+ this.prefix = "pelican_auth_";
4
+ this.defaultTTL = 5 * 60 * 1000;
5
+ this.memoryCache = new Map();
6
+ }
7
+ set(key, value, options = {}) {
8
+ const { ttlMs = this.defaultTTL, useSessionStorage = true } = options;
9
+ const expiresAt = Date.now() + ttlMs;
10
+ const data = { value, expiresAt };
11
+ if (useSessionStorage) {
12
+ try {
13
+ sessionStorage.setItem(`${this.prefix}${key}`, JSON.stringify(data));
14
+ }
15
+ catch (error) {
16
+ console.warn("SessionStorage unavailable, using memory:", error);
17
+ this.setMemory(key, data);
18
+ }
19
+ }
20
+ else {
21
+ this.setMemory(key, data);
22
+ }
23
+ }
24
+ get(key) {
25
+ try {
26
+ const stored = sessionStorage.getItem(`${this.prefix}${key}`);
27
+ if (stored) {
28
+ const data = JSON.parse(stored);
29
+ if (Date.now() > data.expiresAt) {
30
+ this.remove(key);
31
+ return null;
32
+ }
33
+ return data.value;
34
+ }
35
+ }
36
+ catch (error) {
37
+ }
38
+ return this.getMemory(key);
39
+ }
40
+ remove(key) {
41
+ try {
42
+ sessionStorage.removeItem(`${this.prefix}${key}`);
43
+ }
44
+ catch (error) {
45
+ }
46
+ this.memoryCache.delete(key);
47
+ }
48
+ clear() {
49
+ try {
50
+ Object.keys(sessionStorage).forEach((key) => {
51
+ if (key.startsWith(this.prefix)) {
52
+ sessionStorage.removeItem(key);
53
+ }
54
+ });
55
+ }
56
+ catch (error) {
57
+ }
58
+ this.memoryCache.clear();
59
+ }
60
+ setMemory(key, data) {
61
+ this.memoryCache.set(key, data);
62
+ const ttl = data.expiresAt - Date.now();
63
+ setTimeout(() => {
64
+ this.memoryCache.delete(key);
65
+ }, ttl);
66
+ }
67
+ getMemory(key) {
68
+ const data = this.memoryCache.get(key);
69
+ if (!data)
70
+ return null;
71
+ if (Date.now() > data.expiresAt) {
72
+ this.memoryCache.delete(key);
73
+ return null;
74
+ }
75
+ return data.value;
76
+ }
77
+ }
78
+ const storage = new AuthStorage();
79
+ export const storeAuthSession = (sessionId, sessionKey, ttlMs) => {
80
+ storage.set("session", { sessionId, sessionKey }, { ttlMs });
81
+ };
82
+ export const getAuthSession = () => {
83
+ return storage.get("session");
84
+ };
85
+ export const clearAuthSession = () => {
86
+ storage.remove("session");
87
+ };
88
+ export const clearAllAuthData = () => {
89
+ storage.clear();
90
+ };
91
+ export default storage;
92
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/utilities/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { ISocketMessage } from "../types/types";
2
+ type TransportHandlers = {
3
+ onOpen?: () => void;
4
+ onMessage?: (msg: ISocketMessage) => void;
5
+ onError?: (err: Event) => void;
6
+ onClose?: (ev: CloseEvent) => void;
7
+ };
8
+ export declare class Transport {
9
+ private socket?;
10
+ private handlers;
11
+ private reconnectAttempts;
12
+ private maxReconnectAttempts;
13
+ private isExplicitlyClosed;
14
+ private url?;
15
+ constructor(handlers: TransportHandlers);
16
+ connect(url: string): void;
17
+ private attemptReconnect;
18
+ send(payload: ISocketMessage): void;
19
+ close(): void;
20
+ }
21
+ export {};
22
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/utilities/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,KAAK,iBAAiB,GAAG;IACvB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,IAAI,CAAC;CACpC,CAAC;AAEF,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAC,CAAY;IAC3B,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,GAAG,CAAC,CAAS;gBAET,QAAQ,EAAE,iBAAiB;IAIvC,OAAO,CAAC,GAAG,EAAE,MAAM;IA8BnB,OAAO,CAAC,gBAAgB;IAaxB,IAAI,CAAC,OAAO,EAAE,cAAc;IAM5B,KAAK;CAIN"}
@@ -0,0 +1,57 @@
1
+ export class Transport {
2
+ constructor(handlers) {
3
+ this.reconnectAttempts = 0;
4
+ this.maxReconnectAttempts = 5;
5
+ this.isExplicitlyClosed = false;
6
+ this.handlers = handlers;
7
+ }
8
+ connect(url) {
9
+ this.url = url;
10
+ this.isExplicitlyClosed = false;
11
+ this.socket = new WebSocket(url);
12
+ this.socket.onopen = () => {
13
+ this.reconnectAttempts = 0;
14
+ this.handlers.onOpen?.();
15
+ };
16
+ this.socket.onmessage = (e) => {
17
+ try {
18
+ const data = JSON.parse(e.data);
19
+ this.handlers.onMessage?.(data);
20
+ }
21
+ catch (err) {
22
+ console.error("Failed to parse message", err);
23
+ }
24
+ };
25
+ this.socket.onerror = (e) => {
26
+ this.handlers.onError?.(e);
27
+ };
28
+ this.socket.onclose = (e) => {
29
+ this.handlers.onClose?.(e);
30
+ if (!this.isExplicitlyClosed) {
31
+ this.attemptReconnect();
32
+ }
33
+ };
34
+ }
35
+ attemptReconnect() {
36
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
37
+ console.error("❌ Max reconnect attempts reached");
38
+ return;
39
+ }
40
+ this.reconnectAttempts++;
41
+ const delay = Math.pow(2, this.reconnectAttempts) * 500;
42
+ setTimeout(() => {
43
+ if (this.url)
44
+ this.connect(this.url);
45
+ }, delay);
46
+ }
47
+ send(payload) {
48
+ if (this.socket?.readyState === WebSocket.OPEN) {
49
+ this.socket.send(JSON.stringify(payload));
50
+ }
51
+ }
52
+ close() {
53
+ this.isExplicitlyClosed = true;
54
+ this.socket?.close();
55
+ }
56
+ }
57
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/utilities/transport.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,SAAS;IAQpB,YAAY,QAA2B;QAL/B,sBAAiB,GAAG,CAAC,CAAC;QACtB,yBAAoB,GAAG,CAAC,CAAC;QACzB,uBAAkB,GAAG,KAAK,CAAC;QAIjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,GAAW;QACjB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAEjC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;YACxB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3B,CAAC,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAe,EAAE,EAAE;YAC1C,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC;YAClC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;YAChD,CAAC;QACH,CAAC,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAQ,EAAE,EAAE;YACjC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAa,EAAE,EAAE;YACtC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAG3B,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC7B,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAEO,gBAAgB;QACtB,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,GAAG,CAAC;QACxD,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,IAAI,CAAC,GAAG;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,OAAuB;QAC1B,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pelican-identity/auth-core",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Framework-agnostic authentication SDK for Pelican Identity",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",