@passlock/client 0.9.0

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.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/dist/authentication/authenticate.d.ts +22 -0
  4. package/dist/authentication/authenticate.d.ts.map +1 -0
  5. package/dist/authentication/authenticate.fixture.d.ts +36 -0
  6. package/dist/authentication/authenticate.fixture.d.ts.map +1 -0
  7. package/dist/authentication/authenticate.fixture.js +52 -0
  8. package/dist/authentication/authenticate.fixture.js.map +1 -0
  9. package/dist/authentication/authenticate.js +69 -0
  10. package/dist/authentication/authenticate.js.map +1 -0
  11. package/dist/authentication/authenticate.test.d.ts +2 -0
  12. package/dist/authentication/authenticate.test.d.ts.map +1 -0
  13. package/dist/authentication/authenticate.test.js +111 -0
  14. package/dist/authentication/authenticate.test.js.map +1 -0
  15. package/dist/capabilities/capabilities.d.ts +18 -0
  16. package/dist/capabilities/capabilities.d.ts.map +1 -0
  17. package/dist/capabilities/capabilities.js +35 -0
  18. package/dist/capabilities/capabilities.js.map +1 -0
  19. package/dist/config.d.ts +22 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +20 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/connection/connection.d.ts +9 -0
  24. package/dist/connection/connection.d.ts.map +1 -0
  25. package/dist/connection/connection.fixture.d.ts +12 -0
  26. package/dist/connection/connection.fixture.d.ts.map +1 -0
  27. package/dist/connection/connection.fixture.js +20 -0
  28. package/dist/connection/connection.fixture.js.map +1 -0
  29. package/dist/connection/connection.js +21 -0
  30. package/dist/connection/connection.js.map +1 -0
  31. package/dist/connection/connection.test.d.ts +2 -0
  32. package/dist/connection/connection.test.d.ts.map +1 -0
  33. package/dist/connection/connection.test.js +34 -0
  34. package/dist/connection/connection.test.js.map +1 -0
  35. package/dist/effect.d.ts +33 -0
  36. package/dist/effect.d.ts.map +1 -0
  37. package/dist/effect.js +62 -0
  38. package/dist/effect.js.map +1 -0
  39. package/dist/email/email.d.ts +37 -0
  40. package/dist/email/email.d.ts.map +1 -0
  41. package/dist/email/email.fixture.d.ts +33 -0
  42. package/dist/email/email.fixture.d.ts.map +1 -0
  43. package/dist/email/email.fixture.js +30 -0
  44. package/dist/email/email.fixture.js.map +1 -0
  45. package/dist/email/email.js +78 -0
  46. package/dist/email/email.js.map +1 -0
  47. package/dist/email/email.test.d.ts +2 -0
  48. package/dist/email/email.test.d.ts.map +1 -0
  49. package/dist/email/email.test.js +101 -0
  50. package/dist/email/email.test.js.map +1 -0
  51. package/dist/event/event.d.ts +9 -0
  52. package/dist/event/event.d.ts.map +1 -0
  53. package/dist/event/event.js +23 -0
  54. package/dist/event/event.js.map +1 -0
  55. package/dist/event/event.node.test.d.ts +2 -0
  56. package/dist/event/event.node.test.d.ts.map +1 -0
  57. package/dist/event/event.node.test.js +14 -0
  58. package/dist/event/event.node.test.js.map +1 -0
  59. package/dist/event/event.test.d.ts +2 -0
  60. package/dist/event/event.test.d.ts.map +1 -0
  61. package/dist/event/event.test.js +30 -0
  62. package/dist/event/event.test.js.map +1 -0
  63. package/dist/exit.d.ts +64 -0
  64. package/dist/exit.d.ts.map +1 -0
  65. package/dist/exit.js +106 -0
  66. package/dist/exit.js.map +1 -0
  67. package/dist/index.d.ts +110 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +108 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/logging/eventLogger.d.ts +18 -0
  72. package/dist/logging/eventLogger.d.ts.map +1 -0
  73. package/dist/logging/eventLogger.js +32 -0
  74. package/dist/logging/eventLogger.js.map +1 -0
  75. package/dist/logging/eventLogger.test.d.ts +2 -0
  76. package/dist/logging/eventLogger.test.d.ts.map +1 -0
  77. package/dist/logging/eventLogger.test.js +74 -0
  78. package/dist/logging/eventLogger.test.js.map +1 -0
  79. package/dist/registration/register.d.ts +29 -0
  80. package/dist/registration/register.d.ts.map +1 -0
  81. package/dist/registration/register.fixture.d.ts +40 -0
  82. package/dist/registration/register.fixture.d.ts.map +1 -0
  83. package/dist/registration/register.fixture.js +65 -0
  84. package/dist/registration/register.fixture.js.map +1 -0
  85. package/dist/registration/register.js +84 -0
  86. package/dist/registration/register.js.map +1 -0
  87. package/dist/registration/register.test.d.ts +2 -0
  88. package/dist/registration/register.test.d.ts.map +1 -0
  89. package/dist/registration/register.test.js +122 -0
  90. package/dist/registration/register.test.js.map +1 -0
  91. package/dist/storage/storage.d.ts +53 -0
  92. package/dist/storage/storage.d.ts.map +1 -0
  93. package/dist/storage/storage.fixture.d.ts +6 -0
  94. package/dist/storage/storage.fixture.d.ts.map +1 -0
  95. package/dist/storage/storage.fixture.js +26 -0
  96. package/dist/storage/storage.fixture.js.map +1 -0
  97. package/dist/storage/storage.js +102 -0
  98. package/dist/storage/storage.js.map +1 -0
  99. package/dist/storage/storage.test.d.ts +2 -0
  100. package/dist/storage/storage.test.d.ts.map +1 -0
  101. package/dist/storage/storage.test.js +122 -0
  102. package/dist/storage/storage.test.js.map +1 -0
  103. package/dist/test/fixtures.d.ts +14 -0
  104. package/dist/test/fixtures.d.ts.map +1 -0
  105. package/dist/test/fixtures.js +39 -0
  106. package/dist/test/fixtures.js.map +1 -0
  107. package/dist/user/user.d.ts +18 -0
  108. package/dist/user/user.d.ts.map +1 -0
  109. package/dist/user/user.fixture.d.ts +8 -0
  110. package/dist/user/user.fixture.d.ts.map +1 -0
  111. package/dist/user/user.fixture.js +17 -0
  112. package/dist/user/user.fixture.js.map +1 -0
  113. package/dist/user/user.js +23 -0
  114. package/dist/user/user.js.map +1 -0
  115. package/dist/user/user.test.d.ts +2 -0
  116. package/dist/user/user.test.d.ts.map +1 -0
  117. package/dist/user/user.test.js +37 -0
  118. package/dist/user/user.test.js.map +1 -0
  119. package/package.json +87 -0
  120. package/src/authentication/authenticate.fixture.ts +72 -0
  121. package/src/authentication/authenticate.test.ts +207 -0
  122. package/src/authentication/authenticate.ts +147 -0
  123. package/src/capabilities/capabilities.ts +81 -0
  124. package/src/config.ts +43 -0
  125. package/src/connection/connection.fixture.ts +27 -0
  126. package/src/connection/connection.test.ts +61 -0
  127. package/src/connection/connection.ts +51 -0
  128. package/src/effect.ts +278 -0
  129. package/src/email/email.fixture.ts +49 -0
  130. package/src/email/email.test.ts +186 -0
  131. package/src/email/email.ts +139 -0
  132. package/src/event/event.node.test.ts +20 -0
  133. package/src/event/event.test.ts +37 -0
  134. package/src/event/event.ts +25 -0
  135. package/src/index.ts +275 -0
  136. package/src/logging/eventLogger.test.ts +102 -0
  137. package/src/logging/eventLogger.ts +35 -0
  138. package/src/registration/register.fixture.ts +94 -0
  139. package/src/registration/register.test.ts +247 -0
  140. package/src/registration/register.ts +178 -0
  141. package/src/storage/storage.fixture.ts +33 -0
  142. package/src/storage/storage.test.ts +196 -0
  143. package/src/storage/storage.ts +165 -0
  144. package/src/test/fixtures.ts +51 -0
  145. package/src/user/user.fixture.ts +23 -0
  146. package/src/user/user.test.ts +53 -0
  147. package/src/user/user.ts +50 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Passlock
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ <div align="center">
2
+ <a href="https://github.com/passlock-dev/passkeys-frontend">
3
+ <img src="https://github.com/passlock-dev/passkeys-frontend/assets/208345/53ee00d3-8e6c-49ea-b43c-3f901450c73b" alt="Passlock logo" width="80" height="80">
4
+ </a>
5
+ </div>
6
+
7
+ <a name="readme-top"></a>
8
+ <h1 align="center">Serverless Passkeys</h1>
9
+
10
+ <p align="center">
11
+ Simple, yet powerful passkey library for React, Angular, Vue, Svelte and other frameworks.
12
+ <br />
13
+ <a href="https://passlock.dev"><strong>Project website »</strong></a>
14
+ <br />
15
+ <a href="https://passlock.dev/#demo">View Demo</a>
16
+ ·
17
+ <a href="https://docs.passlock.dev">Documentation</a>
18
+ ·
19
+ <a href="https://docs.passlock.dev/docs/tutorial/intro">Tutorial</a>
20
+ </p>
21
+ </div>
22
+
23
+ <br />
24
+
25
+ # Features
26
+
27
+ Passkeys and the WebAuthn API are quite complex. We've taken an opinionated approach to the implementation and feature set to simplify things for you. Following the 80/20 principle we've tried to focus on the features most valuable to developers and users. We welcome feature requests so do [get in touch][contact].
28
+
29
+ 1. **☝🏻 Biometrics** - We've made it really easy to implement facial or fingerprint recognition in your webapps.
30
+
31
+ 2. **🔐 Step up authentication** - Require biometric or PIN verification for some actions e.g. changing account details, whilst allowing frictionless authentication for others.
32
+
33
+ 3. **✉️ Mailbox verification** - Passlock also handles mailbox verification emails (which are more complex than you might think!)
34
+
35
+ 3. **🖥️ Full management console** - Manage all security related aspects of your userbase through a web base console.
36
+
37
+ 5. **🕵️ Audit trail** - View a full audit trail for each user: when they add a new passkey, when they login, verify their email address and much more.
38
+
39
+ # Screenshot
40
+
41
+ ![Passlock user profile](https://github.com/passlock-dev/passkeys/assets/208345/a4a5c4b8-86cb-4076-bd26-7c29ed2151c6)
42
+ <p align="center">Viewing a user's authentication activity on their profile page</p>
@@ -0,0 +1,22 @@
1
+ import { type BadRequest, InternalBrowserError, type NotSupported } from '@passlock/shared/dist/error/error';
2
+ import type { VerificationErrors } from '@passlock/shared/dist/rpc/authentication';
3
+ import { RpcClient } from '@passlock/shared/dist/rpc/rpc';
4
+ import type { AuthenticationCredential, Principal, UserVerification } from '@passlock/shared/dist/schema/schema';
5
+ import { Context, Effect as E, Layer } from 'effect';
6
+ import { Capabilities } from '../capabilities/capabilities';
7
+ import { StorageService } from '../storage/storage';
8
+ export type AuthenticationRequest = {
9
+ userVerification?: UserVerification;
10
+ };
11
+ export type AuthenticationErrors = NotSupported | BadRequest | VerificationErrors;
12
+ export type GetCredential = (options: CredentialRequestOptions) => E.Effect<AuthenticationCredential, InternalBrowserError>;
13
+ export declare const GetCredential: Context.Tag<GetCredential, GetCredential>;
14
+ export type AuthenticationService = {
15
+ authenticatePasskey: (data: AuthenticationRequest) => E.Effect<Principal, AuthenticationErrors>;
16
+ };
17
+ export declare const AuthenticationService: Context.Tag<AuthenticationService, AuthenticationService>;
18
+ type Dependencies = GetCredential | Capabilities | StorageService | RpcClient;
19
+ export declare const authenticatePasskey: (request: AuthenticationRequest) => E.Effect<Principal, AuthenticationErrors, Dependencies>;
20
+ export declare const AuthenticateServiceLive: Layer.Layer<AuthenticationService, never, Capabilities | StorageService | GetCredential | RpcClient>;
21
+ export {};
22
+ //# sourceMappingURL=authenticate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../../src/authentication/authenticate.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,UAAU,EACf,oBAAoB,EACpB,KAAK,YAAY,EAClB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,KAAK,EACV,kBAAkB,EAAC,MAAM,0CAA0C,CAAC;AAKtE,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACzD,OAAO,KAAK,EACV,wBAAwB,EACxB,SAAS,EACV,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAAc,MAAM,QAAQ,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAKnD,MAAM,MAAM,qBAAqB,GAAG;IAAE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAAA;AAI3E,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,UAAU,GAAG,kBAAkB,CAAA;AAIjF,MAAM,MAAM,aAAa,GAAG,CAC1B,OAAO,EAAE,wBAAwB,KAC9B,CAAC,CAAC,MAAM,CAAC,wBAAwB,EAAE,oBAAoB,CAAC,CAAA;AAC7D,eAAO,MAAM,aAAa,2CAAqD,CAAA;AAI/E,MAAM,MAAM,qBAAqB,GAAG;IAClC,mBAAmB,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAA;CAChG,CAAA;AAED,eAAO,MAAM,qBAAqB,2DAEjC,CAAA;AA4CD,KAAK,YAAY,GAAG,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,SAAS,CAAA;AAE7E,eAAO,MAAM,mBAAmB,YACrB,qBAAqB,KAC7B,EAAE,MAAM,CAAC,SAAS,EAAE,oBAAoB,EAAE,YAAY,CAgCxD,CAAA;AAKD,eAAO,MAAM,uBAAuB,sGASnC,CAAA"}
@@ -0,0 +1,36 @@
1
+ import { OptionsRes, VerificationReq, VerificationRes } from '@passlock/shared/dist/rpc/authentication';
2
+ import { RpcClient } from '@passlock/shared/dist/rpc/rpc';
3
+ import type { AuthenticationCredential } from '@passlock/shared/dist/schema/schema';
4
+ import { Layer as L } from 'effect';
5
+ import { type AuthenticationRequest, GetCredential } from './authenticate';
6
+ export declare const session = "session";
7
+ export declare const token = "token";
8
+ export declare const code = "code";
9
+ export declare const authType = "passkey";
10
+ export declare const expireAt: number;
11
+ export declare const request: AuthenticationRequest;
12
+ export declare const optionsRes: OptionsRes;
13
+ export declare const credential: AuthenticationCredential;
14
+ export declare const verificationReq: VerificationReq;
15
+ export declare const verificationRes: VerificationRes;
16
+ export declare const getCredentialTest: L.Layer<GetCredential, never, never>;
17
+ export declare const rpcClientTest: L.Layer<RpcClient, never, never>;
18
+ export declare const principal: {
19
+ readonly token: string;
20
+ readonly subject: {
21
+ readonly id: string;
22
+ readonly email: string;
23
+ readonly firstName: string;
24
+ readonly lastName: string;
25
+ readonly emailVerified: boolean;
26
+ };
27
+ readonly authStatement: {
28
+ readonly authType: "email" | "passkey";
29
+ readonly userVerified: boolean;
30
+ readonly authTimestamp: Date;
31
+ };
32
+ readonly expireAt: Date;
33
+ };
34
+ export declare const capabilitiesTest: L.Layer<import("../capabilities/capabilities").Capabilities, never, never>;
35
+ export declare const storageServiceTest: L.Layer<import("../storage/storage").StorageService, never, never>;
36
+ //# sourceMappingURL=authenticate.fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.fixture.d.ts","sourceRoot":"","sources":["../../src/authentication/authenticate.fixture.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,eAAe,EACf,eAAe,EAChB,MAAM,0CAA0C,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACzD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AACnF,OAAO,EAAe,KAAK,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAE,KAAK,qBAAqB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAI1E,eAAO,MAAM,OAAO,YAAY,CAAA;AAChC,eAAO,MAAM,KAAK,UAAU,CAAA;AAC5B,eAAO,MAAM,IAAI,SAAS,CAAA;AAC1B,eAAO,MAAM,QAAQ,YAAY,CAAA;AACjC,eAAO,MAAM,QAAQ,QAAqB,CAAA;AAE1C,eAAO,MAAM,OAAO,EAAE,qBAErB,CAAA;AAED,eAAO,MAAM,UAAU,YAQrB,CAAA;AAEF,eAAO,MAAM,UAAU,EAAE,wBAYxB,CAAA;AAED,eAAO,MAAM,eAAe,iBAA+C,CAAA;AAE3E,eAAO,MAAM,eAAe,iBAAyD,CAAA;AAErF,eAAO,MAAM,iBAAiB,sCAG7B,CAAA;AAED,eAAO,MAAM,aAAa,kCAWzB,CAAA;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;CAAqB,CAAA;AAC3C,eAAO,MAAM,gBAAgB,4EAA4B,CAAA;AACzD,eAAO,MAAM,kBAAkB,oEAA8B,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { BadRequest } from '@passlock/shared/dist/error/error';
2
+ import { OptionsRes, VerificationReq, VerificationRes, } from '@passlock/shared/dist/rpc/authentication';
3
+ import { RpcClient } from '@passlock/shared/dist/rpc/rpc';
4
+ import { Effect as E, Layer as L } from 'effect';
5
+ import { GetCredential } from './authenticate';
6
+ import * as Fixtures from '../test/fixtures';
7
+ export const session = 'session';
8
+ export const token = 'token';
9
+ export const code = 'code';
10
+ export const authType = 'passkey';
11
+ export const expireAt = Date.now() + 10000;
12
+ export const request = {
13
+ userVerification: 'preferred',
14
+ };
15
+ export const optionsRes = new OptionsRes({
16
+ session,
17
+ publicKey: {
18
+ rpId: 'passlock.dev',
19
+ challenge: 'FKZSl_saKu5OXjLLwoq8eK3wlD8XgpGiS10SszW5RiE',
20
+ timeout: 60000,
21
+ userVerification: 'preferred',
22
+ },
23
+ });
24
+ export const credential = {
25
+ id: '1',
26
+ type: 'public-key',
27
+ rawId: 'id',
28
+ response: {
29
+ clientDataJSON: '',
30
+ authenticatorData: '',
31
+ signature: '',
32
+ userHandle: null,
33
+ },
34
+ clientExtensionResults: {},
35
+ authenticatorAttachment: null,
36
+ };
37
+ export const verificationReq = new VerificationReq({ session, credential });
38
+ export const verificationRes = new VerificationRes({ principal: Fixtures.principal });
39
+ export const getCredentialTest = L.succeed(GetCredential, GetCredential.of(() => E.succeed(credential)));
40
+ export const rpcClientTest = L.succeed(RpcClient, RpcClient.of({
41
+ preConnect: () => E.succeed({ warmed: true }),
42
+ isExistingUser: () => E.succeed({ existingUser: true }),
43
+ verifyEmail: () => E.succeed({ verified: true }),
44
+ getRegistrationOptions: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
45
+ verifyRegistrationCredential: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
46
+ getAuthenticationOptions: () => E.succeed(optionsRes),
47
+ verifyAuthenticationCredential: () => E.succeed(verificationRes),
48
+ }));
49
+ export const principal = Fixtures.principal;
50
+ export const capabilitiesTest = Fixtures.capabilitiesTest;
51
+ export const storageServiceTest = Fixtures.storageServiceTest;
52
+ //# sourceMappingURL=authenticate.fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.fixture.js","sourceRoot":"","sources":["../../src/authentication/authenticate.fixture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Passkey authentication effects
3
+ */
4
+ import { parseRequestOptionsFromJSON, } from '@github/webauthn-json/browser-ponyfill';
5
+ import { InternalBrowserError, } from '@passlock/shared/dist/error/error';
6
+ import { OptionsReq, VerificationReq, } from '@passlock/shared/dist/rpc/authentication';
7
+ import { RpcClient } from '@passlock/shared/dist/rpc/rpc';
8
+ import { Context, Effect as E, Layer, flow, pipe } from 'effect';
9
+ import { Capabilities } from '../capabilities/capabilities';
10
+ import { StorageService } from '../storage/storage';
11
+ export const GetCredential = Context.GenericTag('@services/Get');
12
+ export const AuthenticationService = Context.GenericTag('@services/AuthenticationService');
13
+ /* Utilities */
14
+ const fetchOptions = (req) => {
15
+ return E.gen(function* (_) {
16
+ yield* _(E.logDebug('Making request'));
17
+ const rpcClient = yield* _(RpcClient);
18
+ const { publicKey, session } = yield* _(rpcClient.getAuthenticationOptions(req));
19
+ yield* _(E.logDebug('Converting Passlock options to CredentialRequestOptions'));
20
+ const options = yield* _(toRequestOptions({ publicKey }));
21
+ return { options, session };
22
+ });
23
+ };
24
+ const toRequestOptions = (options) => {
25
+ return pipe(E.try(() => parseRequestOptionsFromJSON(options)), E.mapError(error => new InternalBrowserError({
26
+ message: 'Browser was unable to create credential request options',
27
+ detail: String(error.error),
28
+ })));
29
+ };
30
+ const verifyCredential = (req) => {
31
+ return E.gen(function* (_) {
32
+ yield* _(E.logDebug('Making request'));
33
+ const rpcClient = yield* _(RpcClient);
34
+ const { principal } = yield* _(rpcClient.verifyAuthenticationCredential(req));
35
+ return principal;
36
+ });
37
+ };
38
+ export const authenticatePasskey = (request) => {
39
+ const effect = E.gen(function* (_) {
40
+ yield* _(E.logInfo('Checking if browser supports Passkeys'));
41
+ const capabilities = yield* _(Capabilities);
42
+ yield* _(capabilities.passkeySupport);
43
+ yield* _(E.logInfo('Fetching authentication options from Passlock'));
44
+ const { options, session } = yield* _(fetchOptions(new OptionsReq(request)));
45
+ yield* _(E.logInfo('Looking up credential'));
46
+ const get = yield* _(GetCredential);
47
+ const credential = yield* _(get(options));
48
+ yield* _(E.logInfo('Verifying credential with Passlock'));
49
+ const principal = yield* _(verifyCredential(new VerificationReq({ credential, session })));
50
+ const storageService = yield* _(StorageService);
51
+ yield* _(storageService.storeToken(principal));
52
+ yield* _(E.logDebug('Stored token in local storage'));
53
+ yield* _(E.logDebug('Defering local token deletion'));
54
+ const delayedClearTokenE = pipe(storageService.clearExpiredToken('passkey'), E.delay('6 minutes'), E.fork);
55
+ yield* _(delayedClearTokenE);
56
+ return principal;
57
+ });
58
+ return E.catchTag(effect, 'InternalBrowserError', e => E.die(e));
59
+ };
60
+ /* Live */
61
+ /* v8 ignore start */
62
+ export const AuthenticateServiceLive = Layer.effect(AuthenticationService, E.gen(function* (_) {
63
+ const context = yield* _(E.context());
64
+ return AuthenticationService.of({
65
+ authenticatePasskey: flow(authenticatePasskey, E.provide(context)),
66
+ });
67
+ }));
68
+ /* v8 ignore stop */
69
+ //# sourceMappingURL=authenticate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../src/authentication/authenticate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=authenticate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.test.d.ts","sourceRoot":"","sources":["../../src/authentication/authenticate.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ import { RpcClient } from '@passlock/shared/dist/rpc/rpc';
2
+ import { Effect as E, Layer as L, Layer, LogLevel, Logger, pipe } from 'effect';
3
+ import { describe, expect, test, vi } from 'vitest';
4
+ import { mock } from 'vitest-mock-extended';
5
+ import { AuthenticateServiceLive, AuthenticationService, GetCredential } from './authenticate';
6
+ import * as Fixture from './authenticate.fixture';
7
+ import { StorageService } from '../storage/storage';
8
+ describe('authenticate should', () => {
9
+ test('return a valid principal', async () => {
10
+ const assertions = E.gen(function* (_) {
11
+ const service = yield* _(AuthenticationService);
12
+ const result = yield* _(service.authenticatePasskey({ userVerification: 'preferred' }));
13
+ expect(result).toEqual(Fixture.principal);
14
+ });
15
+ const service = pipe(AuthenticateServiceLive, L.provide(Fixture.getCredentialTest), L.provide(Fixture.capabilitiesTest), L.provide(Fixture.storageServiceTest), L.provide(Fixture.rpcClientTest));
16
+ const effect = pipe(E.provide(assertions, service), Logger.withMinimumLogLevel(LogLevel.None));
17
+ return E.runPromise(effect);
18
+ });
19
+ test('pass the authentication request to the backend', async () => {
20
+ const assertions = E.gen(function* (_) {
21
+ const service = yield* _(AuthenticationService);
22
+ yield* _(service.authenticatePasskey({ userVerification: 'preferred' }));
23
+ const rpcClient = yield* _(RpcClient);
24
+ expect(rpcClient.getAuthenticationOptions).toHaveBeenCalledOnce();
25
+ expect(rpcClient.verifyAuthenticationCredential).toHaveBeenCalledOnce();
26
+ });
27
+ const rpcClientTest = L.effect(RpcClient, E.sync(() => {
28
+ const rpcMock = mock();
29
+ rpcMock.getAuthenticationOptions.mockReturnValue(E.succeed(Fixture.optionsRes));
30
+ rpcMock.verifyAuthenticationCredential.mockReturnValue(E.succeed(Fixture.verificationRes));
31
+ return rpcMock;
32
+ }));
33
+ const service = pipe(AuthenticateServiceLive, L.provide(Fixture.getCredentialTest), L.provide(Fixture.capabilitiesTest), L.provide(Fixture.storageServiceTest), L.provide(rpcClientTest));
34
+ const layers = Layer.merge(service, rpcClientTest);
35
+ const effect = pipe(E.provide(assertions, layers), Logger.withMinimumLogLevel(LogLevel.None));
36
+ return E.runPromise(effect);
37
+ });
38
+ test('send the credential to the backend', async () => {
39
+ const assertions = E.gen(function* (_) {
40
+ const service = yield* _(AuthenticationService);
41
+ yield* _(service.authenticatePasskey({ userVerification: 'preferred' }));
42
+ const rpcClient = yield* _(RpcClient);
43
+ expect(rpcClient.getAuthenticationOptions).toHaveBeenCalledOnce();
44
+ expect(rpcClient.verifyAuthenticationCredential).toHaveBeenCalledWith(Fixture.verificationReq);
45
+ });
46
+ const rpcClientTest = L.effect(RpcClient, E.sync(() => {
47
+ const rpcMock = mock();
48
+ rpcMock.getAuthenticationOptions.mockReturnValue(E.succeed(Fixture.optionsRes));
49
+ rpcMock.verifyAuthenticationCredential.mockReturnValue(E.succeed(Fixture.verificationRes));
50
+ return rpcMock;
51
+ }));
52
+ const service = pipe(AuthenticateServiceLive, L.provide(Fixture.getCredentialTest), L.provide(Fixture.capabilitiesTest), L.provide(Fixture.storageServiceTest), L.provide(rpcClientTest));
53
+ const layers = Layer.merge(service, rpcClientTest);
54
+ const effect = pipe(E.provide(assertions, layers), Logger.withMinimumLogLevel(LogLevel.None));
55
+ return E.runPromise(effect);
56
+ });
57
+ test('store the credential in local storage', async () => {
58
+ const assertions = E.gen(function* (_) {
59
+ const service = yield* _(AuthenticationService);
60
+ yield* _(service.authenticatePasskey({ userVerification: 'preferred' }));
61
+ const storageService = yield* _(StorageService);
62
+ expect(storageService.storeToken).toHaveBeenCalledWith(Fixture.principal);
63
+ });
64
+ const storageServiceTest = L.effect(StorageService, E.sync(() => {
65
+ const storageMock = mock();
66
+ storageMock.storeToken.mockReturnValue(E.unit);
67
+ storageMock.clearExpiredToken.mockReturnValue(E.unit);
68
+ return storageMock;
69
+ }));
70
+ const service = pipe(AuthenticateServiceLive, L.provide(Fixture.getCredentialTest), L.provide(Fixture.capabilitiesTest), L.provide(Fixture.rpcClientTest), L.provide(storageServiceTest));
71
+ const layers = Layer.merge(service, storageServiceTest);
72
+ const effect = pipe(E.provide(assertions, layers), Logger.withMinimumLogLevel(LogLevel.None));
73
+ return E.runPromise(effect);
74
+ });
75
+ test('schedule deletion of the local token', async () => {
76
+ const assertions = E.gen(function* (_) {
77
+ const service = yield* _(AuthenticationService);
78
+ yield* _(service.authenticatePasskey({ userVerification: 'preferred' }));
79
+ const storageService = yield* _(StorageService);
80
+ expect(storageService.clearExpiredToken).toHaveBeenCalledWith('passkey');
81
+ });
82
+ const storageServiceTest = L.effect(StorageService, E.sync(() => {
83
+ const storageMock = mock();
84
+ storageMock.storeToken.mockReturnValue(E.unit);
85
+ storageMock.clearExpiredToken.mockReturnValue(E.unit);
86
+ return storageMock;
87
+ }));
88
+ const service = pipe(AuthenticateServiceLive, L.provide(Fixture.getCredentialTest), L.provide(Fixture.capabilitiesTest), L.provide(Fixture.rpcClientTest), L.provide(storageServiceTest));
89
+ const layers = Layer.merge(service, storageServiceTest);
90
+ const effect = pipe(E.provide(assertions, layers), Logger.withMinimumLogLevel(LogLevel.None));
91
+ return E.runPromise(effect);
92
+ });
93
+ test("return an error if the browser can't create a credential", async () => {
94
+ const assertions = E.gen(function* (_) {
95
+ const service = yield* _(AuthenticationService);
96
+ yield* _(service.authenticatePasskey({ userVerification: 'preferred' }));
97
+ const getCredential = yield* _(GetCredential);
98
+ expect(getCredential).toHaveBeenCalledOnce();
99
+ });
100
+ const getCredentialTest = L.effect(GetCredential, E.sync(() => {
101
+ const getCredentialMock = vi.fn();
102
+ getCredentialMock.mockReturnValue(E.succeed(Fixture.credential));
103
+ return getCredentialMock;
104
+ }));
105
+ const service = pipe(AuthenticateServiceLive, L.provide(Fixture.storageServiceTest), L.provide(Fixture.capabilitiesTest), L.provide(Fixture.rpcClientTest), L.provide(getCredentialTest));
106
+ const layers = Layer.merge(service, getCredentialTest);
107
+ const effect = pipe(E.provide(assertions, layers), Logger.withMinimumLogLevel(LogLevel.None));
108
+ return E.runPromise(effect);
109
+ });
110
+ });
111
+ //# sourceMappingURL=authenticate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.test.js","sourceRoot":"","sources":["../../src/authentication/authenticate.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACzE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAC3C,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9F,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGnD,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAA;YAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;YAEvF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAC3C,CAAC,CAAC,CAAA;QAEF,MAAM,OAAO,GAAG,IAAI,CAClB,uBAAuB,EACvB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EACpC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EACnC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,EACrC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CACjC,CAAA;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;QAE9F,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAA;YAC/C,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;YAExE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YACrC,MAAM,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,oBAAoB,EAAE,CAAA;YACjE,MAAM,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC,oBAAoB,EAAE,CAAA;QACzE,CAAC,CAAC,CAAA;QAEF,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAC5B,SAAS,EACT,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,EAAa,CAAA;YAEjC,OAAO,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAA;YAC/E,OAAO,CAAC,8BAA8B,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;YAE1F,OAAO,OAAO,CAAA;QAChB,CAAC,CAAC,CACH,CAAA;QAED,MAAM,OAAO,GAAG,IAAI,CAClB,uBAAuB,EACvB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EACpC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EACnC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,EACrC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CACzB,CAAA;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;QAE7F,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAA;YAC/C,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;YAExE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YACrC,MAAM,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,oBAAoB,EAAE,CAAA;YACjE,MAAM,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;QAChG,CAAC,CAAC,CAAA;QAEF,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAC5B,SAAS,EACT,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,EAAa,CAAA;YAEjC,OAAO,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAA;YAC/E,OAAO,CAAC,8BAA8B,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;YAE1F,OAAO,OAAO,CAAA;QAChB,CAAC,CAAC,CACH,CAAA;QAED,MAAM,OAAO,GAAG,IAAI,CAClB,uBAAuB,EACvB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EACpC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EACnC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,EACrC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CACzB,CAAA;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;QAE7F,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAA;YAC/C,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;YAExE,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAA;YAC/C,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAC3E,CAAC,CAAC,CAAA;QAEF,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CACjC,cAAc,EACd,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACV,MAAM,WAAW,GAAG,IAAI,EAAkB,CAAA;YAE1C,WAAW,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAC9C,WAAW,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAErD,OAAO,WAAW,CAAA;QACpB,CAAC,CAAC,CACH,CAAA;QAED,MAAM,OAAO,GAAG,IAAI,CAClB,uBAAuB,EACvB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EACpC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EACnC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,EAChC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAC9B,CAAA;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAA;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;QAE7F,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAA;YAC/C,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;YAExE,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAA;YAC/C,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAA;QAC1E,CAAC,CAAC,CAAA;QAEF,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CACjC,cAAc,EACd,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACV,MAAM,WAAW,GAAG,IAAI,EAAkB,CAAA;YAE1C,WAAW,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAC9C,WAAW,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAErD,OAAO,WAAW,CAAA;QACpB,CAAC,CAAC,CACH,CAAA;QAED,MAAM,OAAO,GAAG,IAAI,CAClB,uBAAuB,EACvB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EACpC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EACnC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,EAChC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAC9B,CAAA;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAA;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;QAE7F,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAA;YAC/C,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;YAExE,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;YAC7C,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,EAAE,CAAA;QAC9C,CAAC,CAAC,CAAA;QAEF,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAChC,aAAa,EACb,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACV,MAAM,iBAAiB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAA;YAEjC,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAA;YAEhE,OAAO,iBAAiB,CAAA;QAC1B,CAAC,CAAC,CACH,CAAA;QAED,MAAM,OAAO,GAAG,IAAI,CAClB,uBAAuB,EACvB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,EACrC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EACnC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,EAChC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAC7B,CAAA;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAA;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;QAE7F,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Test if the browser supports passkeys, conditional UI etc
3
+ */
4
+ import { NotSupported } from '@passlock/shared/dist/error/error';
5
+ import { Context, Effect as E, Layer } from 'effect';
6
+ export type Capabilities = {
7
+ passkeySupport: E.Effect<void, NotSupported>;
8
+ isPasskeySupport: E.Effect<boolean>;
9
+ autofillSupport: E.Effect<void, NotSupported>;
10
+ isAutofillSupport: E.Effect<boolean>;
11
+ };
12
+ export declare const Capabilities: Context.Tag<Capabilities, Capabilities>;
13
+ export declare const passkeySupport: E.Effect<void, NotSupported, never>;
14
+ export declare const isPasskeySupport: E.Effect<boolean, never, never>;
15
+ export declare const autofillSupport: E.Effect<void, NotSupported, never>;
16
+ export declare const isAutofillSupport: E.Effect<boolean, never, never>;
17
+ export declare const capabilitiesLive: Layer.Layer<Capabilities, never, never>;
18
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/capabilities/capabilities.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAA;AAIpE,MAAM,MAAM,YAAY,GAAG;IACzB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IAC5C,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACnC,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IAC7C,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,eAAO,MAAM,YAAY,yCAA6D,CAAA;AAgCtF,eAAO,MAAM,cAAc,qCAI1B,CAAA;AAED,eAAO,MAAM,gBAAgB,iCAM5B,CAAA;AAED,eAAO,MAAM,eAAe,qCAAoD,CAAA;AAEhF,eAAO,MAAM,iBAAiB,iCAM7B,CAAA;AAKD,eAAO,MAAM,gBAAgB,yCAK3B,CAAA"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Test if the browser supports passkeys, conditional UI etc
3
+ */
4
+ import { NotSupported } from '@passlock/shared/dist/error/error';
5
+ import { Context, Effect as E, Layer, identity, pipe } from 'effect';
6
+ export const Capabilities = Context.GenericTag('@services/Capabilities');
7
+ /* Effects */
8
+ const hasWebAuthn = E.suspend(() => typeof window.PublicKeyCredential === 'function'
9
+ ? E.unit
10
+ : new NotSupported({ message: 'WebAuthn API is not supported on this device' }));
11
+ const hasPlatformAuth = pipe(E.tryPromise(() => window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()), E.filterOrFail(identity, () => new NotSupported({ message: 'No platform authenticator available on this device' })), E.asUnit);
12
+ const hasConditionalUi = pipe(E.tryPromise({
13
+ try: () => window.PublicKeyCredential.isConditionalMediationAvailable(),
14
+ catch: () => new NotSupported({ message: 'Conditional mediation not available on this device' }),
15
+ }), E.filterOrFail(identity, () => new NotSupported({ message: 'Conditional mediation not available on this device' })), E.asUnit);
16
+ export const passkeySupport = pipe(hasWebAuthn, E.andThen(hasPlatformAuth), E.catchTag('UnknownException', e => E.die(e)));
17
+ export const isPasskeySupport = pipe(passkeySupport, E.match({
18
+ onFailure: () => false,
19
+ onSuccess: () => true,
20
+ }));
21
+ export const autofillSupport = pipe(passkeySupport, E.andThen(hasConditionalUi));
22
+ export const isAutofillSupport = pipe(autofillSupport, E.match({
23
+ onFailure: () => false,
24
+ onSuccess: () => true,
25
+ }));
26
+ /* Live */
27
+ /* v8 ignore start */
28
+ export const capabilitiesLive = Layer.succeed(Capabilities, {
29
+ passkeySupport,
30
+ isPasskeySupport,
31
+ autofillSupport,
32
+ isAutofillSupport,
33
+ });
34
+ /* v8 ignore stop */
35
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/capabilities/capabilities.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAWpE,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAe,wBAAwB,CAAC,CAAA;AAEtF,aAAa;AAEb,MAAM,WAAW,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CACjC,OAAO,MAAM,CAAC,mBAAmB,KAAK,UAAU;IAC9C,CAAC,CAAC,CAAC,CAAC,IAAI;IACR,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC,CAClF,CAAA;AAED,MAAM,eAAe,GAAG,IAAI,CAC1B,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,6CAA6C,EAAE,CAAC,EAC9F,CAAC,CAAC,YAAY,CACZ,QAAQ,EACR,GAAG,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,oDAAoD,EAAE,CAAC,CAC1F,EACD,CAAC,CAAC,MAAM,CACT,CAAA;AAED,MAAM,gBAAgB,GAAG,IAAI,CAC3B,CAAC,CAAC,UAAU,CAAC;IACX,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,+BAA+B,EAAE;IACvE,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,oDAAoD,EAAE,CAAC;CACtF,CAAC,EACF,CAAC,CAAC,YAAY,CACZ,QAAQ,EACR,GAAG,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,oDAAoD,EAAE,CAAC,CAC1F,EACD,CAAC,CAAC,MAAM,CACT,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAChC,WAAW,EACX,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,EAC1B,CAAC,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAC9C,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAClC,cAAc,EACd,CAAC,CAAC,KAAK,CAAC;IACN,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK;IACtB,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI;CACtB,CAAC,CACH,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAA;AAEhF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CACnC,eAAe,EACf,CAAC,CAAC,KAAK,CAAC;IACN,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK;IACtB,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI;CACtB,CAAC,CACH,CAAA;AAED,UAAU;AAEV,qBAAqB;AACrB,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE;IAC1D,cAAc;IACd,gBAAgB;IAChB,eAAe;IACf,iBAAiB;CAClB,CAAC,CAAA;AACF,oBAAoB"}
@@ -0,0 +1,22 @@
1
+ import { RpcConfig } from '@passlock/shared/dist/rpc/rpc';
2
+ import { Context, Layer } from 'effect';
3
+ export declare const DefaultEndpoint = "https://api.passlock.dev";
4
+ export type Tenancy = {
5
+ tenancyId: string;
6
+ clientId: string;
7
+ };
8
+ export declare const Tenancy: Context.Tag<Tenancy, Tenancy>;
9
+ /**
10
+ * Allow developers to override the endpoint e.g. to
11
+ * point to a regional endpoint or a self-hosted backend
12
+ */
13
+ export type Endpoint = {
14
+ endpoint?: string;
15
+ };
16
+ export declare const Endpoint: Context.Tag<Endpoint, Endpoint>;
17
+ export type Config = Tenancy & Endpoint;
18
+ export declare const Config: Context.Tag<Config, Config>;
19
+ export declare const buildConfigLayers: (config: Config) => Layer.Layer<Tenancy | Endpoint, never, never>;
20
+ export declare const buildRpcConfigLayers: (config: Config) => Layer.Layer<RpcConfig, never, never>;
21
+ export type RequestDependencies = Endpoint | Tenancy | Storage | RpcConfig;
22
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAGvC,eAAO,MAAM,eAAe,6BAA6B,CAAA;AAEzD,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AACD,eAAO,MAAM,OAAO,+BAAmD,CAAA;AAEvE;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AACD,eAAO,MAAM,QAAQ,iCAAqD,CAAA;AAE1E,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AACvC,eAAO,MAAM,MAAM,6BAAiD,CAAA;AAEpE,eAAO,MAAM,iBAAiB,WAAY,MAAM,kDAI/C,CAAA;AAED,eAAO,MAAM,oBAAoB,WAAY,MAAM,yCAUlD,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAA"}
package/dist/config.js ADDED
@@ -0,0 +1,20 @@
1
+ import { RpcConfig } from '@passlock/shared/dist/rpc/rpc';
2
+ import { Context, Layer } from 'effect';
3
+ export const DefaultEndpoint = 'https://api.passlock.dev';
4
+ export const Tenancy = Context.GenericTag('@services/Tenancy');
5
+ export const Endpoint = Context.GenericTag('@services/Endpoint');
6
+ export const Config = Context.GenericTag('@services/Config');
7
+ export const buildConfigLayers = (config) => {
8
+ const tenancyLayer = Layer.succeed(Tenancy, Tenancy.of(config));
9
+ const endpointLayer = Layer.succeed(Endpoint, Endpoint.of(config));
10
+ return Layer.mergeAll(tenancyLayer, endpointLayer);
11
+ };
12
+ export const buildRpcConfigLayers = (config) => {
13
+ const endpoint = config.endpoint || DefaultEndpoint;
14
+ return Layer.succeed(RpcConfig, RpcConfig.of({
15
+ endpoint: endpoint,
16
+ tenancyId: config.tenancyId,
17
+ clientId: config.clientId,
18
+ }));
19
+ };
20
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAGvC,MAAM,CAAC,MAAM,eAAe,GAAG,0BAA0B,CAAA;AAMzD,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAU,mBAAmB,CAAC,CAAA;AASvE,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAW,oBAAoB,CAAC,CAAA;AAG1E,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAS,kBAAkB,CAAC,CAAA;AAEpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAc,EAAE,EAAE;IAClD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/D,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAClE,OAAO,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,CAAA;AACpD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAc,EAAE,EAAE;IACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,eAAe,CAAA;IACnD,OAAO,KAAK,CAAC,OAAO,CAClB,SAAS,EACT,SAAS,CAAC,EAAE,CAAC;QACX,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { NetworkService, RpcClient, RpcConfig } from '@passlock/shared/dist/rpc/rpc';
2
+ import { Context, Effect as E, Layer } from 'effect';
3
+ export type ConnectionService = {
4
+ preConnect: () => E.Effect<void>;
5
+ };
6
+ export declare const ConnectionService: Context.Tag<ConnectionService, ConnectionService>;
7
+ export declare const preConnect: () => E.Effect<void, never, RpcClient | NetworkService>;
8
+ export declare const ConnectionServiceLive: Layer.Layer<ConnectionService, never, RpcConfig | RpcClient | NetworkService>;
9
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/connection/connection.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACpF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAAc,MAAM,QAAQ,CAAA;AAIhE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CACjC,CAAA;AAED,eAAO,MAAM,iBAAiB,mDAAoE,CAAA;AAmBlG,eAAO,MAAM,UAAU,yDAGtB,CAAA;AAKD,eAAO,MAAM,qBAAqB,+EASjC,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { PreConnectReq, PreConnectRes } from '@passlock/shared/dist/rpc/connection';
2
+ import { RpcClient } from '@passlock/shared/dist/rpc/rpc';
3
+ import { Layer as L } from 'effect';
4
+ export declare const rpcClientTest: L.Layer<RpcClient, never, never>;
5
+ export declare const preConnectReq: PreConnectReq;
6
+ export declare const preConnectRes: PreConnectRes;
7
+ export declare const rpcConfig: {
8
+ endpoint: string;
9
+ tenancyId: string;
10
+ clientId: string;
11
+ };
12
+ //# sourceMappingURL=connection.fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.fixture.d.ts","sourceRoot":"","sources":["../../src/connection/connection.fixture.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACzD,OAAO,EAAe,KAAK,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAGhD,eAAO,MAAM,aAAa,kCAWzB,CAAA;AAED,eAAO,MAAM,aAAa,eAAwB,CAAA;AAClD,eAAO,MAAM,aAAa,eAAsC,CAAA;AAEhE,eAAO,MAAM,SAAS;;;;CAIrB,CAAA"}
@@ -0,0 +1,20 @@
1
+ import { BadRequest } from '@passlock/shared/dist/error/error';
2
+ import { PreConnectReq, PreConnectRes } from '@passlock/shared/dist/rpc/connection';
3
+ import { RpcClient } from '@passlock/shared/dist/rpc/rpc';
4
+ import { Effect as E, Layer as L } from 'effect';
5
+ export const rpcClientTest = L.succeed(RpcClient, RpcClient.of({
6
+ preConnect: () => E.succeed({ warmed: true }),
7
+ isExistingUser: () => E.succeed({ existingUser: true }),
8
+ verifyEmail: () => E.succeed({ verified: true }),
9
+ getRegistrationOptions: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
10
+ verifyRegistrationCredential: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
11
+ getAuthenticationOptions: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
12
+ verifyAuthenticationCredential: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
13
+ }));
14
+ export const preConnectReq = new PreConnectReq({});
15
+ export const preConnectRes = new PreConnectRes({ warmed: true });
16
+ export const rpcConfig = {
17
+ endpoint: 'https://example.com',
18
+ tenancyId: 'tenancyId', clientId: 'clientId'
19
+ };
20
+ //# sourceMappingURL=connection.fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.fixture.js","sourceRoot":"","sources":["../../src/connection/connection.fixture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACzD,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAGhD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,OAAO,CACpC,SAAS,EACT,SAAS,CAAC,EAAE,CAAC;IACX,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC7C,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACvD,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAChD,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACrF,4BAA4B,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC3F,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACvF,8BAA8B,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;CAC9F,CAAC,CACH,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,EAAE,CAAC,CAAA;AAClD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;AAEhE,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,QAAQ,EAAE,qBAAqB;IAC/B,SAAS,EAAE,WAAW,EAAE,QAAQ,EAChC,UAAU;CACX,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Hits the rpc endpoint to warm up a lambda
3
+ */
4
+ import { PreConnectReq } from '@passlock/shared/dist/rpc/connection';
5
+ import { NetworkService, RpcClient, RpcConfig } from '@passlock/shared/dist/rpc/rpc';
6
+ import { Context, Effect as E, Layer, flow, pipe } from 'effect';
7
+ export const ConnectionService = Context.GenericTag('@services/ConnectService');
8
+ /* Effects */
9
+ const hitPrincipal = pipe(E.logInfo('Pre-connecting to Principal endpoint'), E.zipRight(NetworkService), E.flatMap(networkService => networkService.get('/token/token?warm=true')), E.asUnit, E.catchAll(() => E.unit));
10
+ const hitRpc = pipe(E.logInfo('Pre-connecting to RPC endpoint'), E.zipRight(RpcClient), E.flatMap(rpcClient => rpcClient.preConnect(new PreConnectReq({}))), E.asUnit);
11
+ export const preConnect = () => pipe(E.all([hitPrincipal, hitRpc], { concurrency: 2 }), E.asUnit);
12
+ /* Live */
13
+ /* v8 ignore start */
14
+ export const ConnectionServiceLive = Layer.effect(ConnectionService, E.gen(function* (_) {
15
+ const context = yield* _(E.context());
16
+ return ConnectionService.of({
17
+ preConnect: flow(preConnect, E.provide(context)),
18
+ });
19
+ }));
20
+ /* v8 ignore stop */
21
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/connection/connection.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACpF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAQhE,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAoB,0BAA0B,CAAC,CAAA;AAElG,aAAa;AAEb,MAAM,YAAY,GAAG,IAAI,CACvB,CAAC,CAAC,OAAO,CAAC,sCAAsC,CAAC,EACjD,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,EAC1B,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,EACzE,CAAC,CAAC,MAAM,EACR,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACzB,CAAA;AAED,MAAM,MAAM,GAAG,IAAI,CACjB,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAC3C,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EACrB,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EACnE,CAAC,CAAC,MAAM,CACT,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,IAAI,CAClC,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,EACjD,CAAC,CAAC,MAAM,CACT,CAAA;AAED,UAAU;AAEV,qBAAqB;AACrB,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC,MAAM,CAC/C,iBAAiB,EACjB,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAA0C,CAAC,CAAA;IAE7E,OAAO,iBAAiB,CAAC,EAAE,CAAC;QAC1B,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;KACjD,CAAC,CAAA;AACJ,CAAC,CAAC,CACH,CAAA;AACD,oBAAoB"}