@passlock/node 0.9.2 → 0.9.3

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.
package/README.md CHANGED
@@ -45,6 +45,10 @@ Passkeys and the WebAuthn API are quite complex. We've taken an opinionated appr
45
45
  ![Passlock user profile](https://github.com/passlock-dev/passkeys/assets/208345/a4a5c4b8-86cb-4076-bd26-7c29ed2151c6)
46
46
  <p align="center">Viewing a user's authentication activity on their profile page</p>
47
47
 
48
+ ## Requirements
49
+
50
+ Node 16+
51
+
48
52
  ## Usage
49
53
 
50
54
  Generate a secure token in your frontend then use this API to obtain the passkey registration or authentication details:
@@ -1,4 +1,4 @@
1
- import { Context } from "effect";
1
+ import { Context } from 'effect';
2
2
  declare const Config_base: Context.TagClass<Config, "Config", {
3
3
  readonly tenancyId: string;
4
4
  readonly apiKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;;wBAKT,MAAM;qBACT,MAAM;wBACH,MAAM;;AAL9B,qBAAa,MAAO,SAAQ,WAOzB;CAAG"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;;wBAKR,MAAM;qBACT,MAAM;wBACH,MAAM;;AAL9B,qBAAa,MAAO,SAAQ,WAOzB;CAAG"}
@@ -1,4 +1,4 @@
1
- import { Context } from "effect";
2
- export class Config extends Context.Tag("Config")() {
1
+ import { Context } from 'effect';
2
+ export class Config extends Context.Tag('Config')() {
3
3
  }
4
4
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,MAAM,OAAO,MAAO,SAAQ,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAO9C;CAAG"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEhC,MAAM,OAAO,MAAO,SAAQ,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAO9C;CAAG"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { ErrorCode } from "@passlock/shared/dist/error/error.js";
2
- import { type PrincipalRequest } from "./principal/principal.js";
1
+ import { ErrorCode } from '@passlock/shared/dist/error/error.js';
2
+ import { type PrincipalRequest } from './principal/principal.js';
3
3
  export type { PrincipalRequest } from './principal/principal.js';
4
4
  export { ErrorCode } from '@passlock/shared/dist/error/error.js';
5
5
  export declare class PasslockError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyE,MAAM,sCAAsC,CAAC;AAExI,OAAO,EAA0C,KAAK,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAGzG,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEjE,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,mBAAkB;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS;IAK5C,MAAM,CAAC,QAAQ,CAAC,OAAO,UAAW,OAAO,4BAOxC;CACF;AA4DD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;gBAE3C,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAO5E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAQ1B;IAED,cAAc,YAAa,gBAAgB;;;;;;;;;;;;;;;OAKxC;CACJ;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;gBAE3C,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAO5E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAO1B;IAED,cAAc,YAAa,gBAAgB;;;;;;;;;;;;;;;uBAKxC;CACJ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAKV,MAAM,sCAAsC,CAAA;AAG7C,OAAO,EACL,KAAK,gBAAgB,EAItB,MAAM,0BAA0B,CAAA;AAEjC,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAA;AAEhE,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,mBAAkB;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS;IAK5C,MAAM,CAAC,QAAQ,CAAC,OAAO,UAAW,OAAO,4BAOxC;CACF;AAyDD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;gBAE3C,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAW5E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAQ1B;IAED,cAAc,YAAa,gBAAgB;;;;;;;;;;;;;;;OAKxC;CACJ;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;gBAE3C,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAW5E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAI1B;IAED,cAAc,YAAa,gBAAgB;;;;;;;;;;;;;;;uBAKxC;CACJ"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { ErrorCode, InternalServerError } from "@passlock/shared/dist/error/error.js";
2
- import { Effect as E, Layer as L, Runtime, Scope, pipe } from "effect";
3
- import { PrincipalService, PrincipalServiceLive } from "./principal/principal.js";
4
- import { Config } from "./config/config.js";
1
+ import { ErrorCode, Forbidden, InternalServerError, NotFound, Unauthorized, } from '@passlock/shared/dist/error/error.js';
2
+ import { Effect as E, Layer as L, Runtime, Scope, pipe } from 'effect';
3
+ import { Config } from './config/config.js';
4
+ import { PrincipalService, PrincipalServiceLive, StreamResponseLive, } from './principal/principal.js';
5
5
  export { ErrorCode } from '@passlock/shared/dist/error/error.js';
6
6
  export class PasslockError extends Error {
7
7
  _tag = 'PasslockError';
@@ -54,8 +54,8 @@ const transformErrors = (effect) => {
54
54
  export class PasslockUnsafe {
55
55
  runtime;
56
56
  constructor(config) {
57
- const rpcConfig = L.succeed(Config, Config.of(config));
58
- const allLayers = pipe(PrincipalServiceLive, L.provide(rpcConfig));
57
+ const configLive = L.succeed(Config, Config.of(config));
58
+ const allLayers = pipe(PrincipalServiceLive, L.provide(configLive), L.provide(StreamResponseLive));
59
59
  const scope = E.runSync(Scope.make());
60
60
  this.runtime = E.runSync(L.toRuntime(allLayers).pipe(Scope.extend(scope)));
61
61
  }
@@ -67,8 +67,8 @@ export class PasslockUnsafe {
67
67
  export class Passlock {
68
68
  runtime;
69
69
  constructor(config) {
70
- const rpcConfig = L.succeed(Config, Config.of(config));
71
- const allLayers = pipe(PrincipalServiceLive, L.provide(rpcConfig));
70
+ const configLive = L.succeed(Config, Config.of(config));
71
+ const allLayers = pipe(PrincipalServiceLive, L.provide(configLive), L.provide(StreamResponseLive));
72
72
  const scope = E.runSync(Scope.make());
73
73
  this.runtime = E.runSync(L.toRuntime(allLayers).pipe(Scope.extend(scope)));
74
74
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,12 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
1
3
  import { Forbidden, InternalServerError, NotFound, Unauthorized } from '@passlock/shared/dist/error/error.js';
2
4
  import { Principal } from '@passlock/shared/dist/schema/schema.js';
3
- import { Context, Effect as E, Layer } from "effect";
4
- import { Config } from "../config/config.js";
5
+ import { Context, Effect as E, Layer, Stream } from 'effect';
6
+ import * as https from 'https';
7
+ import { Config } from '../config/config.js';
8
+ export type StreamResponse = (options: https.RequestOptions) => Stream.Stream<Buffer, PrincipalErrors>;
9
+ export declare const StreamResponse: Context.Tag<StreamResponse, StreamResponse>;
5
10
  export type PrincipalErrors = NotFound | Unauthorized | Forbidden | InternalServerError;
6
11
  export type PrincipalRequest = {
7
12
  token: string;
@@ -10,6 +15,11 @@ export type PrincipalService = {
10
15
  fetchPrincipal: (request: PrincipalRequest) => E.Effect<Principal, PrincipalErrors>;
11
16
  };
12
17
  export declare const PrincipalService: Context.Tag<PrincipalService, PrincipalService>;
13
- export declare const fetchPrincipal: (request: PrincipalRequest) => E.Effect<Principal, PrincipalErrors, Config>;
14
- export declare const PrincipalServiceLive: Layer.Layer<PrincipalService, never, Config>;
18
+ export declare const buildError: (res: {
19
+ statusCode?: number | undefined;
20
+ statusMessage?: string | undefined;
21
+ }) => NotFound | Unauthorized | Forbidden | InternalServerError;
22
+ export declare const fetchPrincipal: (request: PrincipalRequest) => E.Effect<Principal, PrincipalErrors, StreamResponse | Config>;
23
+ export declare const StreamResponseLive: Layer.Layer<StreamResponse, never, never>;
24
+ export declare const PrincipalServiceLive: Layer.Layer<PrincipalService, never, Config | StreamResponse>;
15
25
  //# sourceMappingURL=principal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"principal.d.ts","sourceRoot":"","sources":["../../src/principal/principal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAA;AAC7G,OAAO,EAAE,SAAS,EAAgB,MAAM,wCAAwC,CAAA;AAChF,OAAO,EAAkB,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAA0C,MAAM,QAAQ,CAAA;AAE5G,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAI5C,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,GAAG,mBAAmB,CAAA;AACvF,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAA;CACpF,CAAA;AAED,eAAO,MAAM,gBAAgB,iDAA8D,CAAA;AAgD3F,eAAO,MAAM,cAAc,YAAa,gBAAgB,KAAG,EAAE,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,MAAM,CA8BrG,CAAA;AAKD,eAAO,MAAM,oBAAoB,8CAQhC,CAAA"}
1
+ {"version":3,"file":"principal.d.ts","sourceRoot":"","sources":["../../src/principal/principal.ts"],"names":[],"mappings":";;AAAA,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,YAAY,EACb,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAgB,MAAM,wCAAwC,CAAA;AAEhF,OAAO,EAAkB,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAAU,MAAM,EAAc,MAAM,QAAQ,CAAA;AAChG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAI5C,MAAM,MAAM,cAAc,GAAG,CAC3B,OAAO,EAAE,KAAK,CAAC,cAAc,KAC1B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;AAC3C,eAAO,MAAM,cAAc,6CAAiE,CAAA;AAM5F,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,GAAG,mBAAmB,CAAA;AACvF,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAA;CACpF,CAAA;AAED,eAAO,MAAM,gBAAgB,iDAA8D,CAAA;AAuB3F,eAAO,MAAM,UAAU,QAAS;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC,8DAaA,CAAA;AAaD,eAAO,MAAM,cAAc,YAChB,gBAAgB,KACxB,EAAE,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,cAAc,GAAG,MAAM,CAuC9D,CAAA;AAKD,eAAO,MAAM,kBAAkB,2CAW7B,CAAA;AAEF,eAAO,MAAM,oBAAoB,+DAQhC,CAAA"}
@@ -0,0 +1,17 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import type { RequestOptions } from 'https';
3
+ import type { Principal } from '@passlock/shared/dist/schema/schema.js';
4
+ import { Context, Effect as E, Layer as L, Ref } from 'effect';
5
+ import { type PrincipalService } from './principal.js';
6
+ import { Config } from '../config/config.js';
7
+ export declare const principal: Principal;
8
+ export declare const tenancyId = "tenancyId";
9
+ export declare const apiKey = "apiKey";
10
+ export declare const configTest: L.Layer<Config, never, never>;
11
+ declare const State_base: Context.TagClass<State, "State", Ref.Ref<RequestOptions | undefined>>;
12
+ export declare class State extends State_base {
13
+ }
14
+ export declare const buildEffect: <A, E>(assertions: E.Effect<A, E, PrincipalService | State>) => E.Effect<void, E>;
15
+ export declare const buildErrorEffect: (statusCode: number) => <A>(assertions: E.Effect<void, A, PrincipalService>) => E.Effect<void, A>;
16
+ export {};
17
+ //# sourceMappingURL=principal.fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principal.fixture.d.ts","sourceRoot":"","sources":["../../src/principal/principal.fixture.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAoB,GAAG,EAAgB,MAAM,QAAQ,CAAA;AAC9F,OAAO,EACL,KAAK,gBAAgB,EAItB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,eAAO,MAAM,SAAS,EAAE,SAevB,CAAA;AAED,eAAO,MAAM,SAAS,cAAc,CAAA;AACpC,eAAO,MAAM,MAAM,WAAW,CAAA;AAE9B,eAAO,MAAM,UAAU,+BAAsD,CAAA;;AAE7E,qBAAa,KAAM,SAAQ,UAAkE;CAAG;AAEhG,eAAO,MAAM,WAAW,qBACV,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC,KACnD,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAsBlB,CAAA;AAED,eAAO,MAAM,gBAAgB,eACd,MAAM,qBACH,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,gBAAgB,CAAC,KAAG,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAgBrE,CAAA"}
@@ -0,0 +1,43 @@
1
+ import { Context, Effect as E, Layer as L, LogLevel, Logger, Ref, Stream, pipe } from 'effect';
2
+ import { PrincipalServiceLive, StreamResponse, buildError, } from './principal.js';
3
+ import { Config } from '../config/config.js';
4
+ export const principal = {
5
+ token: 'token',
6
+ subject: {
7
+ id: '1',
8
+ email: 'john.doe@gmail.com',
9
+ firstName: 'john',
10
+ lastName: 'doe',
11
+ emailVerified: false,
12
+ },
13
+ authStatement: {
14
+ authType: 'email',
15
+ userVerified: false,
16
+ authTimestamp: new Date(0),
17
+ },
18
+ expireAt: new Date(0),
19
+ };
20
+ export const tenancyId = 'tenancyId';
21
+ export const apiKey = 'apiKey';
22
+ export const configTest = L.succeed(Config, Config.of({ tenancyId, apiKey }));
23
+ export class State extends Context.Tag('State')() {
24
+ }
25
+ export const buildEffect = (assertions) => {
26
+ const responseStreamTest = L.effect(StreamResponse, E.gen(function* (_) {
27
+ const ref = yield* _(State);
28
+ const buff = Buffer.from(JSON.stringify(principal));
29
+ return options => pipe(Stream.fromEffect(Ref.set(ref, options)), Stream.zipRight(Stream.make(buff)));
30
+ }));
31
+ const service = pipe(PrincipalServiceLive, L.provide(responseStreamTest), L.provide(configTest));
32
+ const args = L.effect(State, Ref.make(undefined));
33
+ const effect = pipe(E.provide(assertions, service), E.provide(args), Logger.withMinimumLogLevel(LogLevel.None));
34
+ return effect;
35
+ };
36
+ export const buildErrorEffect = (statusCode) => (assertions) => {
37
+ const responseStreamTest = L.succeed(StreamResponse, () => Stream.fail(buildError({ statusCode })));
38
+ const service = pipe(PrincipalServiceLive, L.provide(responseStreamTest), L.provide(configTest));
39
+ const args = L.effect(State, Ref.make(undefined));
40
+ const effect = pipe(E.provide(assertions, service), E.provide(args), Logger.withMinimumLogLevel(LogLevel.None));
41
+ return effect;
42
+ };
43
+ //# sourceMappingURL=principal.fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principal.fixture.js","sourceRoot":"","sources":["../../src/principal/principal.fixture.ts"],"names":[],"mappings":"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"}
@@ -1,29 +1,33 @@
1
- import { Forbidden, InternalServerError, NotFound, Unauthorized } from '@passlock/shared/dist/error/error.js';
1
+ import { Forbidden, InternalServerError, NotFound, Unauthorized, } from '@passlock/shared/dist/error/error.js';
2
2
  import { Principal, createParser } from '@passlock/shared/dist/schema/schema.js';
3
- import { Chunk, Console, Context, Effect as E, Layer, Option, Stream, StreamEmit, flow, pipe } from "effect";
4
- import * as https from "https";
5
- import { Config } from "../config/config.js";
3
+ import { Chunk, Console, Context, Effect as E, Layer, Option, Stream, flow, pipe } from 'effect';
4
+ import * as https from 'https';
5
+ import { Config } from '../config/config.js';
6
+ export const StreamResponse = Context.GenericTag('@services/ResponseStream');
6
7
  const parsePrincipal = createParser(Principal);
7
8
  export const PrincipalService = Context.GenericTag('@services/Principal');
9
+ const buildHostname = (endpoint) => {
10
+ return new URL(endpoint || 'https://api.passlock.dev').hostname;
11
+ };
8
12
  const buildOptions = (token) => pipe(Config, E.map(({ endpoint, tenancyId, apiKey }) => ({
9
- hostname: endpoint || 'https://api.passlock.dev',
13
+ hostname: buildHostname(endpoint),
10
14
  port: 443,
11
15
  path: `/${tenancyId}/token/${token}`,
12
16
  method: 'GET',
13
17
  headers: {
14
18
  'Accept': 'application/json',
15
- 'X-API-KEY': apiKey
16
- }
19
+ 'X-API-KEY': apiKey,
20
+ },
17
21
  })));
18
- const buildError = (res) => {
22
+ export const buildError = (res) => {
19
23
  if (res.statusCode === 404)
20
- return new NotFound({ message: "Invalid token" });
24
+ return new NotFound({ message: 'Invalid token' });
21
25
  if (res.statusCode === 401)
22
26
  return new Unauthorized({ message: 'Unauthorized' });
23
27
  if (res.statusCode === 403)
24
28
  return new Forbidden({ message: 'Forbidden' });
25
29
  if (res.statusCode && res.statusMessage)
26
- return new InternalServerError({ message: `${res.statusCode} - ${res.statusMessage}` });
30
+ return new InternalServerError({ message: `${String(res.statusCode)} - ${res.statusMessage}` });
27
31
  if (res.statusCode)
28
32
  return new InternalServerError({ message: String(res.statusCode) });
29
33
  if (res.statusMessage)
@@ -33,26 +37,37 @@ const buildError = (res) => {
33
37
  const fail = (error) => E.fail(Option.some(error));
34
38
  const succeed = (data) => E.succeed(Chunk.of(data));
35
39
  const close = E.fail(Option.none());
36
- const buildStream = (token) => pipe(Stream.fromEffect(buildOptions(token)), Stream.flatMap(options => Stream.async((emit) => {
37
- https.request(options, res => {
38
- if (200 !== res.statusCode)
39
- emit(fail(buildError(res)));
40
- res.on('data', data => emit(succeed(data)));
41
- res.on('close', () => emit(close));
42
- res.on('error', (e) => emit(fail(new InternalServerError({ message: e.message }))));
43
- }).end();
44
- })));
40
+ const buildStream = (token) => pipe(Stream.fromEffect(buildOptions(token)), Stream.zip(StreamResponse), Stream.flatMap(([options, streamResponse]) => streamResponse(options)));
45
41
  export const fetchPrincipal = (request) => {
46
42
  const stream = buildStream(request.token);
47
- const json = pipe(Stream.runCollect(stream), E.map(Chunk.toReadonlyArray), E.map(Buffer.concat), E.flatMap(buffer => E.try({
43
+ const json = pipe(Stream.runCollect(stream), E.map(Chunk.toReadonlyArray), E.map(buffers => Buffer.concat(buffers)), E.flatMap(buffer => E.try({
48
44
  try: () => buffer.toString(),
49
- catch: (e) => new InternalServerError({ message: 'Unable to convert response to string', detail: String(e) })
45
+ catch: e => new InternalServerError({
46
+ message: 'Unable to convert response to string',
47
+ detail: String(e),
48
+ }),
50
49
  })), E.flatMap(buffer => E.try({
51
50
  try: () => JSON.parse(buffer),
52
- catch: (e) => new InternalServerError({ message: 'Unable to parse response to json', detail: String(e) })
53
- })), E.tap(json => Console.log(json)), E.flatMap(json => pipe(parsePrincipal(json), E.tapError(error => Console.error(error.detail)), E.mapError(() => new InternalServerError({ message: "Unable to parse response as Principal" })))));
51
+ catch: e => new InternalServerError({
52
+ message: 'Unable to parse response to json',
53
+ detail: String(e),
54
+ }),
55
+ })), E.flatMap(json => pipe(parsePrincipal(json), E.tapError(error => Console.error(error.detail)), E.mapError(() => new InternalServerError({ message: 'Unable to parse response as Principal' })))));
54
56
  return json;
55
57
  };
58
+ export const StreamResponseLive = Layer.succeed(StreamResponse, options => {
59
+ return Stream.async((emit) => {
60
+ https
61
+ .request(options, res => {
62
+ if (200 !== res.statusCode)
63
+ void emit(fail(buildError(res)));
64
+ res.on('data', (data) => void emit(succeed(data)));
65
+ res.on('close', () => void emit(close));
66
+ res.on('error', e => void emit(fail(new InternalServerError({ message: e.message }))));
67
+ })
68
+ .end();
69
+ });
70
+ });
56
71
  export const PrincipalServiceLive = Layer.effect(PrincipalService, E.gen(function* (_) {
57
72
  const context = yield* _(E.context());
58
73
  return PrincipalService.of({
@@ -1 +1 @@
1
- {"version":3,"file":"principal.js","sourceRoot":"","sources":["../../src/principal/principal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"principal.js","sourceRoot":"","sources":["../../src/principal/principal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=principal.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principal.test.d.ts","sourceRoot":"","sources":["../../src/principal/principal.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ import { Forbidden, InternalServerError, NotFound, Unauthorized, } from '@passlock/shared/dist/error/error.js';
2
+ import { Effect as E, Effect, Ref } from 'effect';
3
+ import { describe, expect, test } from 'vitest';
4
+ import * as Fixture from './principal.fixture.js';
5
+ import { PrincipalService } from './principal.js';
6
+ describe('fetchPrincipal should', () => {
7
+ test('return a valid principal', () => {
8
+ const assertions = E.gen(function* (_) {
9
+ const service = yield* _(PrincipalService);
10
+ const result = yield* _(service.fetchPrincipal({ token: 'token' }));
11
+ expect(result).toEqual(Fixture.principal);
12
+ });
13
+ const effect = Fixture.buildEffect(assertions);
14
+ return E.runPromise(effect);
15
+ });
16
+ test('call the right url', () => {
17
+ const assertions = E.gen(function* (_) {
18
+ const service = yield* _(PrincipalService);
19
+ yield* _(service.fetchPrincipal({ token: 'myToken' }));
20
+ const state = yield* _(Fixture.State);
21
+ const args = yield* _(Ref.get(state));
22
+ expect(args?.hostname).toEqual('api.passlock.dev');
23
+ expect(args?.method).toEqual('GET');
24
+ expect(args?.path).toEqual(`/${Fixture.tenancyId}/token/myToken`);
25
+ });
26
+ const effect = Fixture.buildEffect(assertions);
27
+ return E.runPromise(effect);
28
+ });
29
+ test('pass the api key as a header', () => {
30
+ const assertions = E.gen(function* (_) {
31
+ const service = yield* _(PrincipalService);
32
+ yield* _(service.fetchPrincipal({ token: 'myToken' }));
33
+ const state = yield* _(Fixture.State);
34
+ const args = yield* _(Ref.get(state));
35
+ expect(args?.headers?.['X-API-KEY']).toEqual(Fixture.apiKey);
36
+ });
37
+ const effect = Fixture.buildEffect(assertions);
38
+ return E.runPromise(effect);
39
+ });
40
+ test('propagate a 401 error', () => {
41
+ const assertions = E.gen(function* (_) {
42
+ const service = yield* _(PrincipalService);
43
+ const result = service.fetchPrincipal({ token: 'myToken' });
44
+ const error = yield* _(Effect.flip(result));
45
+ expect(error).toBeInstanceOf(Unauthorized);
46
+ });
47
+ const effect = Fixture.buildErrorEffect(401)(assertions);
48
+ return E.runPromise(effect);
49
+ });
50
+ test('propagate a 403 error', () => {
51
+ const assertions = E.gen(function* (_) {
52
+ const service = yield* _(PrincipalService);
53
+ const result = service.fetchPrincipal({ token: 'myToken' });
54
+ const error = yield* _(Effect.flip(result));
55
+ expect(error).toBeInstanceOf(Forbidden);
56
+ });
57
+ const effect = Fixture.buildErrorEffect(403)(assertions);
58
+ return E.runPromise(effect);
59
+ });
60
+ test('propagate a 404 error', () => {
61
+ const assertions = E.gen(function* (_) {
62
+ const service = yield* _(PrincipalService);
63
+ const result = service.fetchPrincipal({ token: 'myToken' });
64
+ const error = yield* _(Effect.flip(result));
65
+ expect(error).toBeInstanceOf(NotFound);
66
+ });
67
+ const effect = Fixture.buildErrorEffect(404)(assertions);
68
+ return E.runPromise(effect);
69
+ });
70
+ test('propagate a 500 error', () => {
71
+ const assertions = E.gen(function* (_) {
72
+ const service = yield* _(PrincipalService);
73
+ const result = service.fetchPrincipal({ token: 'myToken' });
74
+ const error = yield* _(Effect.flip(result));
75
+ expect(error).toBeInstanceOf(InternalServerError);
76
+ });
77
+ const effect = Fixture.buildErrorEffect(500)(assertions);
78
+ return E.runPromise(effect);
79
+ });
80
+ });
81
+ //# sourceMappingURL=principal.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principal.test.js","sourceRoot":"","sources":["../../src/principal/principal.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@passlock/node",
3
3
  "type": "module",
4
- "version": "0.9.2",
4
+ "version": "0.9.3",
5
5
  "description": "Server side passkey library for node/express",
6
6
  "keywords": [
7
7
  "passkey",
@@ -22,14 +22,14 @@
22
22
  "email": "team@passlock.dev"
23
23
  },
24
24
  "dependencies": {
25
- "effect": "2.4.9",
26
- "@passlock/shared": "^0.9.2"
25
+ "effect": "2.4.17",
26
+ "@passlock/shared": "^0.9.3"
27
27
  },
28
28
  "devDependencies": {
29
- "@tsconfig/node16": "^16.1.1",
30
- "@types/node": "^20.11.30",
31
- "@typescript-eslint/eslint-plugin": "^7.3.1",
32
- "@typescript-eslint/parser": "^7.3.1",
29
+ "@tsconfig/node18": "^18.2.4",
30
+ "@types/node": "^20.12.4",
31
+ "@typescript-eslint/eslint-plugin": "^7.5.0",
32
+ "@typescript-eslint/parser": "^7.5.0",
33
33
  "@vitest/coverage-v8": "^1.4.0",
34
34
  "@vitest/ui": "^1.4.0",
35
35
  "eslint": "^8.57.0",
@@ -38,11 +38,10 @@
38
38
  "eslint-plugin-import": "^2.29.1",
39
39
  "prettier": "^3.2.5",
40
40
  "rimraf": "^5.0.5",
41
- "tsx": "^4.7.1",
42
- "typescript": "^5.4.2",
43
- "vite": "^5.2.2",
44
- "vitest": "^1.4.0",
45
- "vitest-mock-extended": "^1.3.1"
41
+ "tsx": "^4.7.2",
42
+ "typescript": "^5.4.3",
43
+ "vite": "^5.2.8",
44
+ "vitest": "^1.4.0"
46
45
  },
47
46
  "exports": {
48
47
  ".": {
@@ -1,10 +1,10 @@
1
- import { Context } from "effect";
1
+ import { Context } from 'effect'
2
2
 
3
- export class Config extends Context.Tag("Config")<
3
+ export class Config extends Context.Tag('Config')<
4
4
  Config,
5
- {
6
- readonly tenancyId: string,
7
- readonly apiKey: string,
8
- readonly endpoint?: string
5
+ {
6
+ readonly tenancyId: string
7
+ readonly apiKey: string
8
+ readonly endpoint?: string
9
9
  }
10
- >() {}
10
+ >() {}
package/src/index.ts CHANGED
@@ -1,11 +1,22 @@
1
- import { ErrorCode, InternalServerError, type Forbidden, type NotFound, type Unauthorized } from "@passlock/shared/dist/error/error.js";
2
- import { Effect as E, Layer as L, Runtime, Scope, pipe } from "effect";
3
- import { PrincipalService, PrincipalServiceLive, type PrincipalRequest } from "./principal/principal.js";
4
- import { Config } from "./config/config.js";
1
+ import {
2
+ ErrorCode,
3
+ Forbidden,
4
+ InternalServerError,
5
+ NotFound,
6
+ Unauthorized,
7
+ } from '@passlock/shared/dist/error/error.js'
8
+ import { Effect as E, Layer as L, Runtime, Scope, pipe } from 'effect'
9
+ import { Config } from './config/config.js'
10
+ import {
11
+ type PrincipalRequest,
12
+ PrincipalService,
13
+ PrincipalServiceLive,
14
+ StreamResponseLive,
15
+ } from './principal/principal.js'
5
16
 
6
17
  export type { PrincipalRequest } from './principal/principal.js'
7
18
 
8
- export { ErrorCode } from '@passlock/shared/dist/error/error.js';
19
+ export { ErrorCode } from '@passlock/shared/dist/error/error.js'
9
20
 
10
21
  export class PasslockError extends Error {
11
22
  readonly _tag = 'PasslockError'
@@ -26,11 +37,7 @@ export class PasslockError extends Error {
26
37
  }
27
38
  }
28
39
 
29
- type PasslockErrors =
30
- | NotFound
31
- | Unauthorized
32
- | Forbidden
33
- | InternalServerError
40
+ type PasslockErrors = NotFound | Unauthorized | Forbidden | InternalServerError
34
41
 
35
42
  const hasMessage = (defect: unknown): defect is { message: string } => {
36
43
  return (
@@ -48,7 +55,8 @@ const transformErrors = <A, R>(
48
55
  NotFound: e => E.succeed(new PasslockError(e.message, ErrorCode.NotFound)),
49
56
  Unauthorized: e => E.succeed(new PasslockError(e.message, ErrorCode.Unauthorized)),
50
57
  Forbidden: e => E.succeed(new PasslockError(e.message, ErrorCode.Forbidden)),
51
- InternalServerError: e => E.succeed(new PasslockError(e.message, ErrorCode.InternalServerError)),
58
+ InternalServerError: e =>
59
+ E.succeed(new PasslockError(e.message, ErrorCode.InternalServerError)),
52
60
  })
53
61
 
54
62
  const sandboxed = E.sandbox(withErrorHandling)
@@ -88,8 +96,12 @@ export class PasslockUnsafe {
88
96
  private readonly runtime: Runtime.Runtime<Requirements>
89
97
 
90
98
  constructor(config: { tenancyId: string; apiKey: string; endpoint?: string }) {
91
- const rpcConfig = L.succeed(Config, Config.of(config))
92
- const allLayers = pipe(PrincipalServiceLive, L.provide(rpcConfig))
99
+ const configLive = L.succeed(Config, Config.of(config))
100
+ const allLayers = pipe(
101
+ PrincipalServiceLive,
102
+ L.provide(configLive),
103
+ L.provide(StreamResponseLive),
104
+ )
93
105
  const scope = E.runSync(Scope.make())
94
106
  this.runtime = E.runSync(L.toRuntime(allLayers).pipe(Scope.extend(scope)))
95
107
  }
@@ -116,8 +128,12 @@ export class Passlock {
116
128
  private readonly runtime: Runtime.Runtime<Requirements>
117
129
 
118
130
  constructor(config: { tenancyId: string; apiKey: string; endpoint?: string }) {
119
- const rpcConfig = L.succeed(Config, Config.of(config))
120
- const allLayers = pipe(PrincipalServiceLive, L.provide(rpcConfig))
131
+ const configLive = L.succeed(Config, Config.of(config))
132
+ const allLayers = pipe(
133
+ PrincipalServiceLive,
134
+ L.provide(configLive),
135
+ L.provide(StreamResponseLive),
136
+ )
121
137
  const scope = E.runSync(Scope.make())
122
138
  this.runtime = E.runSync(L.toRuntime(allLayers).pipe(Scope.extend(scope)))
123
139
  }
@@ -125,10 +141,7 @@ export class Passlock {
125
141
  private readonly runPromise = <A, R extends Requirements>(
126
142
  effect: E.Effect<A, PasslockErrors, R>,
127
143
  ) => {
128
- return pipe(
129
- transformErrors(effect),
130
- effect => Runtime.runPromise(this.runtime)(effect)
131
- )
144
+ return pipe(transformErrors(effect), effect => Runtime.runPromise(this.runtime)(effect))
132
145
  }
133
146
 
134
147
  fetchPrincipal = (request: PrincipalRequest) =>
@@ -137,4 +150,4 @@ export class Passlock {
137
150
  E.flatMap(service => service.fetchPrincipal(request)),
138
151
  effect => this.runPromise(effect),
139
152
  )
140
- }
153
+ }
@@ -0,0 +1,80 @@
1
+ import type { RequestOptions } from 'https'
2
+ import type { Principal } from '@passlock/shared/dist/schema/schema.js'
3
+ import { Context, Effect as E, Layer as L, LogLevel, Logger, Ref, Stream, pipe } from 'effect'
4
+ import {
5
+ type PrincipalService,
6
+ PrincipalServiceLive,
7
+ StreamResponse,
8
+ buildError,
9
+ } from './principal.js'
10
+ import { Config } from '../config/config.js'
11
+
12
+ export const principal: Principal = {
13
+ token: 'token',
14
+ subject: {
15
+ id: '1',
16
+ email: 'john.doe@gmail.com',
17
+ firstName: 'john',
18
+ lastName: 'doe',
19
+ emailVerified: false,
20
+ },
21
+ authStatement: {
22
+ authType: 'email',
23
+ userVerified: false,
24
+ authTimestamp: new Date(0),
25
+ },
26
+ expireAt: new Date(0),
27
+ }
28
+
29
+ export const tenancyId = 'tenancyId'
30
+ export const apiKey = 'apiKey'
31
+
32
+ export const configTest = L.succeed(Config, Config.of({ tenancyId, apiKey }))
33
+
34
+ export class State extends Context.Tag('State')<State, Ref.Ref<RequestOptions | undefined>>() {}
35
+
36
+ export const buildEffect = <A, E>(
37
+ assertions: E.Effect<A, E, PrincipalService | State>,
38
+ ): E.Effect<void, E> => {
39
+ const responseStreamTest = L.effect(
40
+ StreamResponse,
41
+ E.gen(function* (_) {
42
+ const ref = yield* _(State)
43
+ const buff = Buffer.from(JSON.stringify(principal))
44
+ return options =>
45
+ pipe(Stream.fromEffect(Ref.set(ref, options)), Stream.zipRight(Stream.make(buff)))
46
+ }),
47
+ )
48
+
49
+ const service = pipe(PrincipalServiceLive, L.provide(responseStreamTest), L.provide(configTest))
50
+
51
+ const args = L.effect(State, Ref.make<RequestOptions | undefined>(undefined))
52
+
53
+ const effect = pipe(
54
+ E.provide(assertions, service),
55
+ E.provide(args),
56
+ Logger.withMinimumLogLevel(LogLevel.None),
57
+ )
58
+
59
+ return effect
60
+ }
61
+
62
+ export const buildErrorEffect =
63
+ (statusCode: number) =>
64
+ <A>(assertions: E.Effect<void, A, PrincipalService>): E.Effect<void, A> => {
65
+ const responseStreamTest = L.succeed(StreamResponse, () =>
66
+ Stream.fail(buildError({ statusCode })),
67
+ )
68
+
69
+ const service = pipe(PrincipalServiceLive, L.provide(responseStreamTest), L.provide(configTest))
70
+
71
+ const args = L.effect(State, Ref.make<RequestOptions | undefined>(undefined))
72
+
73
+ const effect = pipe(
74
+ E.provide(assertions, service),
75
+ E.provide(args),
76
+ Logger.withMinimumLogLevel(LogLevel.None),
77
+ )
78
+
79
+ return effect
80
+ }
@@ -0,0 +1,111 @@
1
+ import {
2
+ Forbidden,
3
+ InternalServerError,
4
+ NotFound,
5
+ Unauthorized,
6
+ } from '@passlock/shared/dist/error/error.js'
7
+ import { Effect as E, Effect, Ref } from 'effect'
8
+ import { describe, expect, test } from 'vitest'
9
+ import * as Fixture from './principal.fixture.js'
10
+ import { PrincipalService } from './principal.js'
11
+
12
+ describe('fetchPrincipal should', () => {
13
+ test('return a valid principal', () => {
14
+ const assertions = E.gen(function* (_) {
15
+ const service = yield* _(PrincipalService)
16
+ const result = yield* _(service.fetchPrincipal({ token: 'token' }))
17
+
18
+ expect(result).toEqual(Fixture.principal)
19
+ })
20
+
21
+ const effect = Fixture.buildEffect(assertions)
22
+
23
+ return E.runPromise(effect)
24
+ })
25
+
26
+ test('call the right url', () => {
27
+ const assertions = E.gen(function* (_) {
28
+ const service = yield* _(PrincipalService)
29
+ yield* _(service.fetchPrincipal({ token: 'myToken' }))
30
+
31
+ const state = yield* _(Fixture.State)
32
+ const args = yield* _(Ref.get(state))
33
+
34
+ expect(args?.hostname).toEqual('api.passlock.dev')
35
+ expect(args?.method).toEqual('GET')
36
+ expect(args?.path).toEqual(`/${Fixture.tenancyId}/token/myToken`)
37
+ })
38
+
39
+ const effect = Fixture.buildEffect(assertions)
40
+
41
+ return E.runPromise(effect)
42
+ })
43
+
44
+ test('pass the api key as a header', () => {
45
+ const assertions = E.gen(function* (_) {
46
+ const service = yield* _(PrincipalService)
47
+ yield* _(service.fetchPrincipal({ token: 'myToken' }))
48
+
49
+ const state = yield* _(Fixture.State)
50
+ const args = yield* _(Ref.get(state))
51
+
52
+ expect(args?.headers?.['X-API-KEY']).toEqual(Fixture.apiKey)
53
+ })
54
+
55
+ const effect = Fixture.buildEffect(assertions)
56
+
57
+ return E.runPromise(effect)
58
+ })
59
+
60
+ test('propagate a 401 error', () => {
61
+ const assertions = E.gen(function* (_) {
62
+ const service = yield* _(PrincipalService)
63
+ const result = service.fetchPrincipal({ token: 'myToken' })
64
+ const error = yield* _(Effect.flip(result))
65
+ expect(error).toBeInstanceOf(Unauthorized)
66
+ })
67
+
68
+ const effect = Fixture.buildErrorEffect(401)(assertions)
69
+
70
+ return E.runPromise(effect)
71
+ })
72
+
73
+ test('propagate a 403 error', () => {
74
+ const assertions = E.gen(function* (_) {
75
+ const service = yield* _(PrincipalService)
76
+ const result = service.fetchPrincipal({ token: 'myToken' })
77
+ const error = yield* _(Effect.flip(result))
78
+ expect(error).toBeInstanceOf(Forbidden)
79
+ })
80
+
81
+ const effect = Fixture.buildErrorEffect(403)(assertions)
82
+
83
+ return E.runPromise(effect)
84
+ })
85
+
86
+ test('propagate a 404 error', () => {
87
+ const assertions = E.gen(function* (_) {
88
+ const service = yield* _(PrincipalService)
89
+ const result = service.fetchPrincipal({ token: 'myToken' })
90
+ const error = yield* _(Effect.flip(result))
91
+ expect(error).toBeInstanceOf(NotFound)
92
+ })
93
+
94
+ const effect = Fixture.buildErrorEffect(404)(assertions)
95
+
96
+ return E.runPromise(effect)
97
+ })
98
+
99
+ test('propagate a 500 error', () => {
100
+ const assertions = E.gen(function* (_) {
101
+ const service = yield* _(PrincipalService)
102
+ const result = service.fetchPrincipal({ token: 'myToken' })
103
+ const error = yield* _(Effect.flip(result))
104
+ expect(error).toBeInstanceOf(InternalServerError)
105
+ })
106
+
107
+ const effect = Fixture.buildErrorEffect(500)(assertions)
108
+
109
+ return E.runPromise(effect)
110
+ })
111
+ })
@@ -1,8 +1,23 @@
1
- import { Forbidden, InternalServerError, NotFound, Unauthorized } from '@passlock/shared/dist/error/error.js'
1
+ import {
2
+ Forbidden,
3
+ InternalServerError,
4
+ NotFound,
5
+ Unauthorized,
6
+ } from '@passlock/shared/dist/error/error.js'
2
7
  import { Principal, createParser } from '@passlock/shared/dist/schema/schema.js'
3
- import { Chunk, Console, Context, Effect as E, Layer, Option, Stream, StreamEmit, flow, pipe } from "effect"
4
- import * as https from "https"
5
- import { Config } from "../config/config.js"
8
+ import type { StreamEmit } from 'effect'
9
+ import { Chunk, Console, Context, Effect as E, Layer, Option, Stream, flow, pipe } from 'effect'
10
+ import * as https from 'https'
11
+ import { Config } from '../config/config.js'
12
+
13
+ /* Dependencies */
14
+
15
+ export type StreamResponse = (
16
+ options: https.RequestOptions,
17
+ ) => Stream.Stream<Buffer, PrincipalErrors>
18
+ export const StreamResponse = Context.GenericTag<StreamResponse>('@services/ResponseStream')
19
+
20
+ /* Service */
6
21
 
7
22
  const parsePrincipal = createParser(Principal)
8
23
 
@@ -15,94 +30,122 @@ export type PrincipalService = {
15
30
 
16
31
  export const PrincipalService = Context.GenericTag<PrincipalService>('@services/Principal')
17
32
 
18
- const buildOptions = (token: string) => pipe(
19
- Config,
20
- E.map(({ endpoint, tenancyId, apiKey }) => ({
21
- hostname: endpoint || 'https://api.passlock.dev',
22
- port: 443,
23
- path: `/${tenancyId}/token/${token}`,
24
- method: 'GET',
25
- headers: {
26
- 'Accept': 'application/json',
27
- 'X-API-KEY': apiKey
28
- }
29
- }))
30
- )
33
+ /* Effects */
34
+
35
+ const buildHostname = (endpoint: string | undefined) => {
36
+ return new URL(endpoint || 'https://api.passlock.dev').hostname
37
+ }
38
+
39
+ const buildOptions = (token: string) =>
40
+ pipe(
41
+ Config,
42
+ E.map(({ endpoint, tenancyId, apiKey }) => ({
43
+ hostname: buildHostname(endpoint),
44
+ port: 443,
45
+ path: `/${tenancyId}/token/${token}`,
46
+ method: 'GET',
47
+ headers: {
48
+ 'Accept': 'application/json',
49
+ 'X-API-KEY': apiKey,
50
+ },
51
+ })),
52
+ )
31
53
 
32
- const buildError = (res: { statusCode?: number | undefined, statusMessage?: string | undefined }) => {
33
- if (res.statusCode === 404) return new NotFound({ message: "Invalid token" })
54
+ export const buildError = (res: {
55
+ statusCode?: number | undefined
56
+ statusMessage?: string | undefined
57
+ }) => {
58
+ if (res.statusCode === 404) return new NotFound({ message: 'Invalid token' })
34
59
  if (res.statusCode === 401) return new Unauthorized({ message: 'Unauthorized' })
35
60
  if (res.statusCode === 403) return new Forbidden({ message: 'Forbidden' })
36
61
 
37
- if (res.statusCode && res.statusMessage) return new InternalServerError({ message: `${res.statusCode} - ${res.statusMessage}` })
38
- if (res.statusCode) return new InternalServerError({ message: String(res.statusCode) })
39
- if (res.statusMessage) return new InternalServerError({ message: res.statusMessage })
62
+ if (res.statusCode && res.statusMessage)
63
+ return new InternalServerError({ message: `${String(res.statusCode)} - ${res.statusMessage}` })
64
+
65
+ if (res.statusCode) return new InternalServerError({ message: String(res.statusCode) })
66
+
67
+ if (res.statusMessage) return new InternalServerError({ message: res.statusMessage })
40
68
 
41
- return new InternalServerError({ message: 'Received non 200 response'})
69
+ return new InternalServerError({ message: 'Received non 200 response' })
42
70
  }
43
71
 
44
72
  const fail = (error: PrincipalErrors) => E.fail(Option.some(error))
45
73
  const succeed = (data: Buffer) => E.succeed(Chunk.of(data))
46
74
  const close = E.fail(Option.none())
47
75
 
48
- const buildStream = (token: string) => pipe(
49
- Stream.fromEffect(buildOptions(token)),
50
- Stream.flatMap(options =>
51
- Stream.async((emit: StreamEmit.Emit<never, PrincipalErrors, Buffer, void>) => {
52
- https.request(options, res => {
53
- if (200 !== res.statusCode) emit(fail(buildError(res)))
54
- res.on('data', data => emit(succeed(data)))
55
- res.on('close', () => emit(close))
56
- res.on('error', (e) => emit(
57
- fail(new InternalServerError({ message: e.message }))
58
- ))
59
- }).end()
60
- })
76
+ const buildStream = (token: string) =>
77
+ pipe(
78
+ Stream.fromEffect(buildOptions(token)),
79
+ Stream.zip(StreamResponse),
80
+ Stream.flatMap(([options, streamResponse]) => streamResponse(options)),
61
81
  )
62
- )
63
82
 
64
- export const fetchPrincipal = (request: PrincipalRequest): E.Effect<Principal, PrincipalErrors, Config> => {
83
+ export const fetchPrincipal = (
84
+ request: PrincipalRequest,
85
+ ): E.Effect<Principal, PrincipalErrors, StreamResponse | Config> => {
65
86
  const stream = buildStream(request.token)
66
87
 
67
88
  const json = pipe(
68
- Stream.runCollect(stream),
89
+ Stream.runCollect(stream),
69
90
  E.map(Chunk.toReadonlyArray),
70
- E.map(Buffer.concat),
71
- E.flatMap(buffer =>
91
+ E.map(buffers => Buffer.concat(buffers)),
92
+ E.flatMap(buffer =>
72
93
  E.try({
73
94
  try: () => buffer.toString(),
74
- catch: (e) => new InternalServerError({ message: 'Unable to convert response to string', detail: String(e) })
75
- })
95
+ catch: e =>
96
+ new InternalServerError({
97
+ message: 'Unable to convert response to string',
98
+ detail: String(e),
99
+ }),
100
+ }),
76
101
  ),
77
- E.flatMap(buffer =>
102
+ E.flatMap(buffer =>
78
103
  E.try({
79
- try: () => JSON.parse(buffer),
80
- catch: (e) => new InternalServerError({ message: 'Unable to parse response to json', detail: String(e) })
81
- })
104
+ try: () => JSON.parse(buffer) as unknown,
105
+ catch: e =>
106
+ new InternalServerError({
107
+ message: 'Unable to parse response to json',
108
+ detail: String(e),
109
+ }),
110
+ }),
82
111
  ),
83
- E.tap(json => Console.log(json)),
84
- E.flatMap(json =>
112
+ E.flatMap(json =>
85
113
  pipe(
86
- parsePrincipal(json),
114
+ parsePrincipal(json),
87
115
  E.tapError(error => Console.error(error.detail)),
88
- E.mapError(() => new InternalServerError({ message: "Unable to parse response as Principal" }))
89
- )
90
- )
116
+ E.mapError(
117
+ () => new InternalServerError({ message: 'Unable to parse response as Principal' }),
118
+ ),
119
+ ),
120
+ ),
91
121
  )
92
-
122
+
93
123
  return json
94
124
  }
95
125
 
96
126
  /* Live */
97
127
 
98
128
  /* v8 ignore start */
129
+ export const StreamResponseLive = Layer.succeed(StreamResponse, options => {
130
+ return Stream.async((emit: StreamEmit.Emit<never, PrincipalErrors, Buffer, void>) => {
131
+ https
132
+ .request(options, res => {
133
+ if (200 !== res.statusCode) void emit(fail(buildError(res)))
134
+ res.on('data', (data: Buffer) => void emit(succeed(data)))
135
+ res.on('close', () => void emit(close))
136
+ res.on('error', e => void emit(fail(new InternalServerError({ message: e.message }))))
137
+ })
138
+ .end()
139
+ })
140
+ })
141
+
99
142
  export const PrincipalServiceLive = Layer.effect(
100
143
  PrincipalService,
101
144
  E.gen(function* (_) {
102
- const context = yield* _(E.context<Config>())
145
+ const context = yield* _(E.context<Config | StreamResponse>())
103
146
  return PrincipalService.of({
104
147
  fetchPrincipal: flow(fetchPrincipal, E.provide(context)),
105
148
  })
106
149
  }),
107
150
  )
108
- /* v8 ignore stop */
151
+ /* v8 ignore stop */