@passlock/client 0.9.22 → 0.9.23

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 (151) hide show
  1. package/dist/authentication/authenticate.d.ts +15 -15
  2. package/dist/authentication/authenticate.fixture.d.ts +20 -6
  3. package/dist/authentication/authenticate.fixture.js +7 -5
  4. package/dist/authentication/authenticate.fixture.js.map +1 -1
  5. package/dist/authentication/authenticate.js +19 -8
  6. package/dist/authentication/authenticate.js.map +1 -1
  7. package/dist/capabilities/capabilities.d.ts +8 -4
  8. package/dist/capabilities/capabilities.js +10 -1
  9. package/dist/capabilities/capabilities.js.map +1 -1
  10. package/dist/connection/connection.d.ts +11 -7
  11. package/dist/connection/connection.fixture.d.ts +2 -2
  12. package/dist/connection/connection.fixture.js +2 -1
  13. package/dist/connection/connection.fixture.js.map +1 -1
  14. package/dist/connection/connection.js +12 -3
  15. package/dist/connection/connection.js.map +1 -1
  16. package/dist/effect.d.ts +22 -45
  17. package/dist/effect.js +55 -51
  18. package/dist/effect.js.map +1 -1
  19. package/dist/email/email.d.ts +38 -11
  20. package/dist/email/email.fixture.d.ts +19 -5
  21. package/dist/email/email.fixture.js +4 -3
  22. package/dist/email/email.fixture.js.map +1 -1
  23. package/dist/email/email.js +43 -7
  24. package/dist/email/email.js.map +1 -1
  25. package/dist/event/event.d.ts +3 -1
  26. package/dist/event/event.js +3 -0
  27. package/dist/event/event.js.map +1 -1
  28. package/dist/index.d.ts +105 -27
  29. package/dist/index.js +101 -50
  30. package/dist/index.js.map +1 -1
  31. package/dist/logging/eventLogger.d.ts +13 -1
  32. package/dist/logging/eventLogger.js +13 -0
  33. package/dist/logging/eventLogger.js.map +1 -1
  34. package/dist/registration/register.d.ts +18 -21
  35. package/dist/registration/register.fixture.d.ts +19 -5
  36. package/dist/registration/register.fixture.js +14 -7
  37. package/dist/registration/register.fixture.js.map +1 -1
  38. package/dist/registration/register.js +18 -9
  39. package/dist/registration/register.js.map +1 -1
  40. package/dist/rpc/authentication.d.ts +0 -1
  41. package/dist/rpc/authentication.js +1 -0
  42. package/dist/rpc/authentication.js.map +1 -1
  43. package/dist/rpc/client.d.ts +4 -1
  44. package/dist/rpc/client.js +12 -2
  45. package/dist/rpc/client.js.map +1 -1
  46. package/dist/rpc/config.d.ts +0 -1
  47. package/dist/rpc/connection.d.ts +0 -1
  48. package/dist/rpc/connection.js +1 -0
  49. package/dist/rpc/connection.js.map +1 -1
  50. package/dist/rpc/registration.d.ts +0 -1
  51. package/dist/rpc/registration.js +1 -0
  52. package/dist/rpc/registration.js.map +1 -1
  53. package/dist/rpc/social.d.ts +0 -1
  54. package/dist/rpc/social.js +1 -0
  55. package/dist/rpc/social.js.map +1 -1
  56. package/dist/rpc/user.d.ts +0 -1
  57. package/dist/rpc/user.js +1 -0
  58. package/dist/rpc/user.js.map +1 -1
  59. package/dist/social/social.d.ts +16 -23
  60. package/dist/social/social.fixture.d.ts +21 -9
  61. package/dist/social/social.fixture.js +8 -14
  62. package/dist/social/social.fixture.js.map +1 -1
  63. package/dist/social/social.js +14 -10
  64. package/dist/social/social.js.map +1 -1
  65. package/dist/storage/storage.d.ts +40 -12
  66. package/dist/storage/storage.fixture.d.ts +2 -2
  67. package/dist/storage/storage.fixture.js +2 -2
  68. package/dist/storage/storage.fixture.js.map +1 -1
  69. package/dist/storage/storage.js +48 -15
  70. package/dist/storage/storage.js.map +1 -1
  71. package/dist/test/fixtures.d.ts +1 -2
  72. package/dist/test/fixtures.js +20 -5
  73. package/dist/test/fixtures.js.map +1 -1
  74. package/dist/user/user.d.ts +8 -5
  75. package/dist/user/user.fixture.d.ts +2 -2
  76. package/dist/user/user.fixture.js +9 -5
  77. package/dist/user/user.fixture.js.map +1 -1
  78. package/dist/user/user.js +9 -3
  79. package/dist/user/user.js.map +1 -1
  80. package/dist/version.d.ts +1 -2
  81. package/dist/version.js +1 -1
  82. package/dist/version.js.map +1 -1
  83. package/package.json +30 -26
  84. package/src/authentication/authenticate.fixture.ts +8 -7
  85. package/src/authentication/authenticate.test.ts +59 -17
  86. package/src/authentication/authenticate.ts +34 -32
  87. package/src/capabilities/capabilities.ts +9 -8
  88. package/src/connection/connection.fixture.ts +2 -1
  89. package/src/connection/connection.test.ts +3 -3
  90. package/src/connection/connection.ts +9 -8
  91. package/src/effect.ts +129 -128
  92. package/src/email/email.fixture.ts +4 -3
  93. package/src/email/email.test.ts +4 -4
  94. package/src/email/email.ts +24 -16
  95. package/src/index.ts +225 -169
  96. package/src/logging/eventLogger.test.ts +1 -1
  97. package/src/logging/eventLogger.ts +2 -2
  98. package/src/registration/register.fixture.ts +14 -8
  99. package/src/registration/register.test.ts +13 -9
  100. package/src/registration/register.ts +37 -34
  101. package/src/rpc/authentication.ts +31 -0
  102. package/src/rpc/client.ts +173 -0
  103. package/src/rpc/config.ts +18 -0
  104. package/src/rpc/connection.ts +24 -0
  105. package/src/rpc/registration.ts +31 -0
  106. package/src/rpc/social.ts +36 -0
  107. package/src/rpc/user.ts +42 -0
  108. package/src/social/social.fixture.ts +10 -18
  109. package/src/social/social.test.ts +13 -29
  110. package/src/social/social.ts +20 -47
  111. package/src/storage/storage.fixture.ts +3 -4
  112. package/src/storage/storage.test.ts +28 -19
  113. package/src/storage/storage.ts +36 -36
  114. package/src/test/fixtures.ts +21 -6
  115. package/src/user/user.fixture.ts +17 -7
  116. package/src/user/user.test.ts +2 -5
  117. package/src/user/user.ts +13 -9
  118. package/src/version.ts +1 -0
  119. package/dist/authentication/authenticate.d.ts.map +0 -1
  120. package/dist/authentication/authenticate.fixture.d.ts.map +0 -1
  121. package/dist/capabilities/capabilities.d.ts.map +0 -1
  122. package/dist/config.d.ts +0 -18
  123. package/dist/config.d.ts.map +0 -1
  124. package/dist/config.js +0 -20
  125. package/dist/config.js.map +0 -1
  126. package/dist/connection/connection.d.ts.map +0 -1
  127. package/dist/connection/connection.fixture.d.ts.map +0 -1
  128. package/dist/effect.d.ts.map +0 -1
  129. package/dist/email/email.d.ts.map +0 -1
  130. package/dist/email/email.fixture.d.ts.map +0 -1
  131. package/dist/event/event.d.ts.map +0 -1
  132. package/dist/index.d.ts.map +0 -1
  133. package/dist/logging/eventLogger.d.ts.map +0 -1
  134. package/dist/registration/register.d.ts.map +0 -1
  135. package/dist/registration/register.fixture.d.ts.map +0 -1
  136. package/dist/rpc/authentication.d.ts.map +0 -1
  137. package/dist/rpc/client.d.ts.map +0 -1
  138. package/dist/rpc/config.d.ts.map +0 -1
  139. package/dist/rpc/connection.d.ts.map +0 -1
  140. package/dist/rpc/registration.d.ts.map +0 -1
  141. package/dist/rpc/social.d.ts.map +0 -1
  142. package/dist/rpc/user.d.ts.map +0 -1
  143. package/dist/social/social.d.ts.map +0 -1
  144. package/dist/social/social.fixture.d.ts.map +0 -1
  145. package/dist/storage/storage.d.ts.map +0 -1
  146. package/dist/storage/storage.fixture.d.ts.map +0 -1
  147. package/dist/test/fixtures.d.ts.map +0 -1
  148. package/dist/user/user.d.ts.map +0 -1
  149. package/dist/user/user.fixture.d.ts.map +0 -1
  150. package/dist/version.d.ts.map +0 -1
  151. package/src/config.ts +0 -42
@@ -6,15 +6,30 @@ export const session = 'session';
6
6
  export const token = 'token';
7
7
  export const code = 'code';
8
8
  export const authType = 'passkey';
9
- export const expireAt = Date.now() + 10000;
9
+ export const expiry = Date.now() + 10000;
10
10
  export const principal = {
11
+ jti: 'token',
11
12
  token: 'token',
13
+ sub: 'user-1',
14
+ iss: 'idp.passlock.dev',
15
+ aud: 'tenancy_id',
16
+ iat: new Date(),
17
+ nbf: new Date(),
18
+ exp: new Date(Date.now() + 5 * 60 * 1000),
19
+ email: 'john.doe@gmail.com',
20
+ givenName: 'john',
21
+ familyName: 'doe',
22
+ emailVerified: false,
23
+ authType: 'passkey',
24
+ authId: 'auth-1',
25
+ userVerified: true,
26
+ // legacy
12
27
  user: {
13
- id: '1',
14
- email: 'john.doe@gmail.com',
28
+ id: 'user-1',
15
29
  givenName: 'john',
16
30
  familyName: 'doe',
17
- emailVerified: false,
31
+ email: 'john.doe@gmail.com',
32
+ emailVerified: false
18
33
  },
19
34
  authStatement: {
20
35
  authType: 'passkey',
@@ -29,7 +44,7 @@ export const capabilitiesTest = L.succeed(Capabilities, Capabilities.of({
29
44
  autofillSupport: E.void,
30
45
  isAutofillSupport: E.succeed(true),
31
46
  }));
32
- export const storedToken = { token, authType, expireAt };
47
+ export const storedToken = { token, authType, expiry };
33
48
  export const storageServiceTest = L.succeed(StorageService, StorageService.of({
34
49
  storeToken: () => E.void,
35
50
  getToken: () => E.succeed(storedToken),
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/test/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAA;AAEjE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAoB,MAAM,uBAAuB,CAAA;AAExE,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAA;AAChC,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAA;AAC5B,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAA;AAC1B,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,CAAA;AACjC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;AAE1C,MAAM,CAAC,MAAM,SAAS,GAAc;IAClC,KAAK,EAAE,OAAO;IACd,IAAI,EAAE;QACJ,EAAE,EAAE,GAAG;QACP,KAAK,EAAE,oBAAoB;QAC3B,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,KAAK;KACrB;IACD,aAAa,EAAE;QACb,QAAQ,EAAE,SAAS;QACnB,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;KAC3B;IACD,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;CACtB,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,OAAO,CACvC,YAAY,EACZ,YAAY,CAAC,EAAE,CAAC;IACd,cAAc,EAAE,CAAC,CAAC,IAAI;IACtB,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACjC,eAAe,EAAE,CAAC,CAAC,IAAI;IACvB,iBAAiB,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;CACnC,CAAC,CACH,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;AAErE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,OAAO,CACzC,cAAc,EACd,cAAc,CAAC,EAAE,CAAC;IAChB,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;IACxB,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IACtC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;IACxB,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;IAC/B,kBAAkB,EAAE,CAAC,CAAC,IAAI;CAC3B,CAAC,CACH,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAA"}
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/test/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAA;AAEjE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAoB,MAAM,uBAAuB,CAAA;AAExE,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAA;AAChC,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAA;AAC5B,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAA;AAC1B,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,CAAA;AACjC,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;AAExC,MAAM,CAAC,MAAM,SAAS,GAAc;IAClC,GAAG,EAAE,OAAO;IACZ,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,kBAAkB;IACvB,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,IAAI,IAAI,EAAE;IACf,GAAG,EAAE,IAAI,IAAI,EAAE;IACf,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IACzC,KAAK,EAAE,oBAAoB;IAC3B,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,KAAK;IACjB,aAAa,EAAE,KAAK;IACpB,QAAQ,EAAE,SAAS;IACnB,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,IAAI;IAClB,SAAS;IACT,IAAI,EAAE;QACJ,EAAE,EAAE,QAAQ;QACZ,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,oBAAoB;QAC3B,aAAa,EAAE,KAAK;KACrB;IACD,aAAa,EAAE;QACb,QAAQ,EAAE,SAAS;QACnB,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;KAC3B;IACD,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;CACtB,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,OAAO,CACvC,YAAY,EACZ,YAAY,CAAC,EAAE,CAAC;IACd,cAAc,EAAE,CAAC,CAAC,IAAI;IACtB,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACjC,eAAe,EAAE,CAAC,CAAC,IAAI;IACvB,iBAAiB,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;CACnC,CAAC,CACH,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;AAEnE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,OAAO,CACzC,cAAc,EACd,cAAc,CAAC,EAAE,CAAC;IAChB,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;IACxB,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IACtC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;IACxB,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;IAC/B,kBAAkB,EAAE,CAAC,CAAC,IAAI;CAC3B,CAAC,CACH,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAA"}
@@ -1,7 +1,10 @@
1
+ /**
2
+ * Check for an existing user
3
+ */
1
4
  import type { BadRequest, Disabled, NotFound } from '@passlock/shared/dist/error/error.js';
2
- import { UserClient } from '@passlock/shared/dist/rpc/user.js';
3
5
  import type { VerifyEmail } from '@passlock/shared/dist/schema/email.js';
4
6
  import { Context, Effect as E, Layer } from 'effect';
7
+ import { UserClient } from '../rpc/user.js';
5
8
  export type Email = {
6
9
  email: string;
7
10
  };
@@ -9,14 +12,14 @@ export type ResendEmail = VerifyEmail & {
9
12
  userId: string;
10
13
  };
11
14
  export type ResendEmailErrors = BadRequest | NotFound | Disabled;
12
- export type UserService = {
15
+ declare const UserService_base: Context.TagClass<UserService, "@services/UserService", {
13
16
  isExistingUser: (request: Email) => E.Effect<boolean, BadRequest>;
14
17
  resendVerificationEmail: (request: ResendEmail) => E.Effect<void, ResendEmailErrors>;
15
- };
16
- export declare const UserService: Context.Tag<UserService, UserService>;
18
+ }>;
19
+ export declare class UserService extends UserService_base {
20
+ }
17
21
  type Dependencies = UserClient;
18
22
  export declare const isExistingUser: (request: Email) => E.Effect<boolean, BadRequest, Dependencies>;
19
23
  export declare const resendVerificationEmail: (request: ResendEmail) => E.Effect<void, ResendEmailErrors, Dependencies>;
20
24
  export declare const UserServiceLive: Layer.Layer<UserService, never, UserClient>;
21
25
  export {};
22
- //# sourceMappingURL=user.d.ts.map
@@ -1,5 +1,6 @@
1
- import { IsExistingUserReq, IsExistingUserRes, ResendEmailReq, ResendEmailRes, UserClient, VerifyEmailRes } from '@passlock/shared/dist/rpc/user.js';
1
+ import { IsExistingUserReq, IsExistingUserRes, ResendEmailReq, ResendEmailRes, VerifyEmailRes } from '@passlock/shared/dist/rpc/user.js';
2
2
  import { Layer as L } from 'effect';
3
+ import { UserClient } from '../rpc/user.js';
3
4
  import type { ResendEmail } from './user.js';
4
5
  export declare const email = "jdoe@gmail.com";
5
6
  export declare const isRegisteredReq: IsExistingUserReq;
@@ -9,4 +10,3 @@ export declare const resendEmailReq: ResendEmail;
9
10
  export declare const rpcResendEmailReq: ResendEmailReq;
10
11
  export declare const rpcResendEmailRes: ResendEmailRes;
11
12
  export declare const rpcClientTest: L.Layer<UserClient, never, never>;
12
- //# sourceMappingURL=user.fixture.d.ts.map
@@ -1,15 +1,19 @@
1
- import { IsExistingUserReq, IsExistingUserRes, ResendEmailReq, ResendEmailRes, UserClient, VerifyEmailRes } from '@passlock/shared/dist/rpc/user.js';
2
- import { Effect as E, Layer as L } from 'effect';
1
+ import { IsExistingUserReq, IsExistingUserRes, ResendEmailReq, ResendEmailRes, VerifyEmailRes, } from '@passlock/shared/dist/rpc/user.js';
2
+ import { Effect as E, Layer as L, Option as O } from 'effect';
3
+ import { UserClient } from '../rpc/user.js';
3
4
  import * as Fixtures from '../test/fixtures.js';
4
5
  export const email = 'jdoe@gmail.com';
5
6
  export const isRegisteredReq = new IsExistingUserReq({ email });
6
- export const isRegisteredRes = new IsExistingUserRes({ existingUser: false });
7
+ export const isRegisteredRes = new IsExistingUserRes({ existingUser: false, detail: O.none() });
7
8
  export const verifyEmailRes = new VerifyEmailRes({ principal: Fixtures.principal });
8
9
  export const resendEmailReq = { userId: '123', method: 'code' };
9
- export const rpcResendEmailReq = new ResendEmailReq({ userId: '123', verifyEmail: { method: 'code' } });
10
+ export const rpcResendEmailReq = new ResendEmailReq({
11
+ userId: '123',
12
+ verifyEmail: { method: 'code' },
13
+ });
10
14
  export const rpcResendEmailRes = new ResendEmailRes({});
11
15
  export const rpcClientTest = L.succeed(UserClient, UserClient.of({
12
- isExistingUser: () => E.succeed({ existingUser: true }),
16
+ isExistingUser: () => E.succeed({ existingUser: true, detail: O.none() }),
13
17
  verifyEmail: () => E.succeed(verifyEmailRes),
14
18
  resendVerificationEmail: () => E.fail(Fixtures.notImplemented),
15
19
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"user.fixture.js","sourceRoot":"","sources":["../../src/user/user.fixture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AACpJ,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAChD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAA;AAG/C,MAAM,CAAC,MAAM,KAAK,GAAG,gBAAgB,CAAA;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,iBAAiB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AAC/D,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,iBAAiB,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;AACnF,MAAM,CAAC,MAAM,cAAc,GAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAC,CAAC,CAAA;AACtG,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,cAAc,CAAC,EAAG,CAAC,CAAA;AAExD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,OAAO,CACpC,UAAU,EACV,UAAU,CAAC,EAAE,CAAC;IACZ,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,cAAc,CAAC;IAC5C,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;CAC/D,CAAC,CACH,CAAA"}
1
+ {"version":3,"file":"user.fixture.js","sourceRoot":"","sources":["../../src/user/user.fixture.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAA;AAG/C,MAAM,CAAC,MAAM,KAAK,GAAG,gBAAgB,CAAA;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,iBAAiB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AAC/D,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,iBAAiB,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;AAC/F,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;AACnF,MAAM,CAAC,MAAM,cAAc,GAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,cAAc,CAAC;IAClD,MAAM,EAAE,KAAK;IACb,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;CAChC,CAAC,CAAA;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,cAAc,CAAC,EAAE,CAAC,CAAA;AAEvD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,OAAO,CACpC,UAAU,EACV,UAAU,CAAC,EAAE,CAAC;IACZ,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IACzE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IAC5C,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;CAC/D,CAAC,CACH,CAAA"}
package/dist/user/user.js CHANGED
@@ -1,6 +1,9 @@
1
- import { IsExistingUserReq, ResendEmailReq, UserClient } from '@passlock/shared/dist/rpc/user.js';
1
+ import { IsExistingUserReq, ResendEmailReq } from '@passlock/shared/dist/rpc/user.js';
2
2
  import { Context, Effect as E, Layer, flow } from 'effect';
3
- export const UserService = Context.GenericTag('@services/UserService');
3
+ import { UserClient } from '../rpc/user.js';
4
+ /* Service */
5
+ export class UserService extends Context.Tag('@services/UserService')() {
6
+ }
4
7
  export const isExistingUser = (request) => {
5
8
  return E.gen(function* (_) {
6
9
  yield* _(E.logInfo('Checking registration status'));
@@ -19,11 +22,14 @@ export const resendVerificationEmail = (request) => {
19
22
  yield* _(rpcClient.resendVerificationEmail(new ResendEmailReq({ userId, verifyEmail })));
20
23
  });
21
24
  };
25
+ /* Live */
26
+ /* v8 ignore start */
22
27
  export const UserServiceLive = Layer.effect(UserService, E.gen(function* (_) {
23
28
  const context = yield* _(E.context());
24
29
  return UserService.of({
25
30
  isExistingUser: flow(isExistingUser, E.provide(context)),
26
- resendVerificationEmail: flow(resendVerificationEmail, E.provide(context))
31
+ resendVerificationEmail: flow(resendVerificationEmail, E.provide(context)),
27
32
  });
28
33
  }));
34
+ /* v8 ignore stop */
29
35
  //# sourceMappingURL=user.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/user/user.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEjG,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAkB1D,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAc,uBAAuB,CAAC,CAAA;AAMnF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAc,EAA+C,EAAE;IAC5F,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACnD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QAEtC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAC1C,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAE3F,OAAO,YAAY,CAAA;IACrB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,OAAoB,EAAmD,EAAE;IAC/G,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACnD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QAEtC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAC1C,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAA;QAC1C,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAA;IAC1F,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAKD,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,CACzC,WAAW,EACX,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAc,CAAC,CAAA;IACjD,OAAO,WAAW,CAAC,EAAE,CAAC;QACpB,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxD,uBAAuB,EAAE,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;KAC3E,CAAC,CAAA;AACJ,CAAC,CAAC,CACH,CAAA"}
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/user/user.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AAErF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAW3C,aAAa;AAEb,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAMlE;CAAG;AAMN,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAc,EAA+C,EAAE;IAC5F,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACnD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QAEtC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAC1C,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAE3F,OAAO,YAAY,CAAA;IACrB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,OAAoB,EAC6B,EAAE;IACnD,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACnD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QAEtC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAC1C,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAA;QAC1C,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAA;IAC1F,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,UAAU;AAEV,qBAAqB;AACrB,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,CACzC,WAAW,EACX,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAc,CAAC,CAAA;IACjD,OAAO,WAAW,CAAC,EAAE,CAAC;QACpB,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxD,uBAAuB,EAAE,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;KAC3E,CAAC,CAAA;AACJ,CAAC,CAAC,CACH,CAAA;AACD,oBAAoB"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1 @@
1
- export declare const PASSLOCK_VERSION = "#{LATEST}#";
2
- //# sourceMappingURL=version.d.ts.map
1
+ export declare const PASSLOCK_CLIENT_VERSION = "0.9.23";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const PASSLOCK_VERSION = '#{LATEST}#';
1
+ export const PASSLOCK_CLIENT_VERSION = '0.9.23';
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAA"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,YAAY,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@passlock/client",
3
- "version": "0.9.22",
4
- "description": "Easy WebAuthn/FIDO Passkey authentication and social login for web apps. This library works with pretty much any frontend/backend stack including React/Next.js, Vue etc.",
3
+ "version": "0.9.23",
4
+ "description": "Passkey authentication and social login for web apps (Typescript). Framework agnostic",
5
5
  "keywords": [
6
6
  "passkey",
7
7
  "passkeys",
@@ -9,6 +9,8 @@
9
9
  "google one tap",
10
10
  "sign in with google",
11
11
  "sign in with apple",
12
+ "svelte",
13
+ "sveltekit",
12
14
  "react",
13
15
  "next",
14
16
  "vue",
@@ -19,7 +21,7 @@
19
21
  "email": "toby@passlock.dev"
20
22
  },
21
23
  "license": "MIT",
22
- "homepage": "https://github.com/passlock-dev/ts-clients",
24
+ "homepage": "https://passlock.dev",
23
25
  "repository": {
24
26
  "type": "git",
25
27
  "url": "git+https://github.com/passlock-dev/ts-clients.git"
@@ -42,45 +44,47 @@
42
44
  "!dist/**/*.spec.*"
43
45
  ],
44
46
  "dependencies": {
47
+ "@effect/schema": "0.70.4",
45
48
  "@github/webauthn-json": "^2.1.1",
46
- "effect": "3.4.8",
47
- "@passlock/shared": "0.9.22"
49
+ "effect": "3.6.3",
50
+ "@passlock/shared": "0.9.23"
48
51
  },
49
52
  "devDependencies": {
50
- "@tsconfig/node18": "^18.2.4",
51
- "@types/node": "^20.14.10",
52
- "@typescript-eslint/eslint-plugin": "^7.15.0",
53
- "@typescript-eslint/parser": "^7.15.0",
54
- "@vitest/coverage-v8": "^2.0.3",
55
- "@vitest/ui": "^2.0.3",
56
- "eslint": "^8.57.0",
53
+ "@qetza/replacetokens": "^1.7.0",
54
+ "@total-typescript/tsconfig": "^1.0.4",
55
+ "@trivago/prettier-plugin-sort-imports": "^4.3.0",
56
+ "@tsconfig/node20": "^20.1.4",
57
+ "@types/node": "^22.2.0",
58
+ "@typescript-eslint/eslint-plugin": "^8.0.1",
59
+ "@typescript-eslint/parser": "^8.0.1",
60
+ "@vitest/coverage-v8": "^2.0.5",
61
+ "@vitest/ui": "^2.0.5",
62
+ "eslint": "^9.9.0",
57
63
  "eslint-config-prettier": "^9.1.0",
58
- "eslint-import-resolver-typescript": "^3.6.1",
59
- "eslint-plugin-import": "^2.29.1",
60
- "jsdom": "^24.1.0",
61
- "prettier": "^3.3.2",
62
- "publint": "^0.1.9",
63
- "rimraf": "^5.0.8",
64
+ "jsdom": "^24.1.1",
65
+ "prettier": "^3.3.3",
66
+ "publint": "^0.2.9",
67
+ "rimraf": "^6.0.1",
64
68
  "tslib": "^2.6.3",
65
- "typescript": "^5.5.3",
66
- "vite": "^5.3.3",
67
- "vitest": "^2.0.3",
68
- "vitest-mock-extended": "^1.3.1"
69
+ "typescript": "^5.5.4",
70
+ "vite": "^5.4.0",
71
+ "vitest": "^2.0.5",
72
+ "vitest-mock-extended": "^2.0.0"
69
73
  },
70
74
  "scripts": {
71
- "clean": "tsc --build --clean",
75
+ "clean": "rimraf ./dist",
72
76
  "typecheck": "tsc --noEmit",
73
77
  "test": "vitest run",
74
78
  "test:watch": "vitest dev",
75
79
  "test:ui": "vitest --coverage.enabled=true --ui",
76
80
  "test:coverage": "vitest run --coverage",
77
- "build": "tsc --build && publint",
81
+ "replaceTokens": "LATEST=${npm_package_version} replacetokens --sources ./dist/version.* --log-level error --missing-var-action keep --use-env > /dev/null",
82
+ "build": "tsc --build && pnpm run replaceTokens && publint",
78
83
  "build:clean": "pnpm run clean && pnpm run build",
79
84
  "build:watch": "tsc --build --watch",
80
85
  "format": "prettier --write \"src/**/*.+(js|ts|json)\"",
81
86
  "lint": "eslint --ext .ts src",
82
87
  "lint:fix": "pnpm run lint --fix",
83
- "ncu": "ncu --peer -x @effect/* -x effect",
84
- "ncu:save": "ncu --peer -x @effect/* -x effect -u"
88
+ "upgrade:deps": "ncu --peer -x effect -x @effect/* -u"
85
89
  }
86
90
  }
@@ -1,14 +1,14 @@
1
1
  import {
2
- AuthenticationClient,
3
2
  OptionsRes,
4
3
  VerificationReq,
5
4
  VerificationRes,
6
5
  } from '@passlock/shared/dist/rpc/authentication.js'
7
6
  import { IsExistingUserRes, VerifyEmailRes } from '@passlock/shared/dist/rpc/user.js'
8
7
  import type { AuthenticationCredential } from '@passlock/shared/dist/schema/passkey.js'
9
- import { Effect as E, Layer as L } from 'effect'
8
+ import { Effect as E, Layer as L, Option as O } from 'effect'
9
+ import { AuthenticationClient } from '../rpc/authentication.js'
10
10
  import * as Fixtures from '../test/fixtures.js'
11
- import { GetCredential, type AuthenticationRequest } from './authenticate.js'
11
+ import { type AuthenticationRequest, GetCredential } from './authenticate.js'
12
12
 
13
13
  export const session = 'session'
14
14
  export const token = 'token'
@@ -17,7 +17,8 @@ export const authType = 'passkey'
17
17
  export const expireAt = Date.now() + 10000
18
18
 
19
19
  export const request: AuthenticationRequest = {
20
- userVerification: 'preferred',
20
+ userVerification: O.some('preferred'),
21
+ email: O.none(),
21
22
  }
22
23
 
23
24
  export const rpcOptionsRes = new OptionsRes({
@@ -48,13 +49,13 @@ export const rpcVerificationReq = new VerificationReq({ session, credential })
48
49
 
49
50
  export const rpcVerificationRes = new VerificationRes({ principal: Fixtures.principal })
50
51
 
51
- export const rpcIsExistingUserRes = new IsExistingUserRes({ existingUser: true })
52
+ export const rpcIsExistingUserRes = new IsExistingUserRes({ existingUser: true, detail: O.none() })
52
53
 
53
54
  export const rpcVerifyEmailRes = new VerifyEmailRes({ principal: Fixtures.principal })
54
55
 
55
56
  export const getCredentialTest = L.succeed(
56
57
  GetCredential,
57
- GetCredential.of(() => E.succeed(credential)),
58
+ GetCredential.of({ getCredential: () => E.succeed(credential) }),
58
59
  )
59
60
 
60
61
  export const rpcClientTest = L.succeed(
@@ -62,7 +63,7 @@ export const rpcClientTest = L.succeed(
62
63
  AuthenticationClient.of({
63
64
  getAuthenticationOptions: () => E.succeed(rpcOptionsRes),
64
65
  verifyAuthenticationCredential: () => E.succeed(rpcVerificationRes),
65
- })
66
+ }),
66
67
  )
67
68
 
68
69
  export const principal = Fixtures.principal
@@ -1,7 +1,7 @@
1
- import { AuthenticationClient } from '@passlock/shared/dist/rpc/authentication.js'
2
- import { Effect as E, Layer as L, Layer, LogLevel, Logger, pipe } from 'effect'
1
+ import { Effect as E, Layer as L, Layer, LogLevel, Logger, Option as O, pipe } from 'effect'
3
2
  import { describe, expect, test, vi } from 'vitest'
4
3
  import { mock } from 'vitest-mock-extended'
4
+ import { AuthenticationClient } from '../rpc/authentication.js'
5
5
  import { StorageService } from '../storage/storage.js'
6
6
  import * as Fixture from './authenticate.fixture.js'
7
7
  import { AuthenticateServiceLive, AuthenticationService, GetCredential } from './authenticate.js'
@@ -10,7 +10,13 @@ describe('authenticate should', () => {
10
10
  test('return a valid principal', async () => {
11
11
  const assertions = E.gen(function* (_) {
12
12
  const service = yield* _(AuthenticationService)
13
- const result = yield* _(service.authenticatePasskey({ userVerification: 'preferred' }))
13
+
14
+ const result = yield* _(
15
+ service.authenticatePasskey({
16
+ email: O.none(),
17
+ userVerification: O.some('preferred'),
18
+ }),
19
+ )
14
20
 
15
21
  expect(result).toEqual(Fixture.principal)
16
22
  })
@@ -31,7 +37,13 @@ describe('authenticate should', () => {
31
37
  test('pass the authentication request to the backend', async () => {
32
38
  const assertions = E.gen(function* (_) {
33
39
  const service = yield* _(AuthenticationService)
34
- yield* _(service.authenticatePasskey({ userVerification: 'preferred' }))
40
+
41
+ yield* _(
42
+ service.authenticatePasskey({
43
+ email: O.none(),
44
+ userVerification: O.some('preferred'),
45
+ }),
46
+ )
35
47
 
36
48
  const rpcClient = yield* _(AuthenticationClient)
37
49
  expect(rpcClient.getAuthenticationOptions).toHaveBeenCalledOnce()
@@ -44,7 +56,9 @@ describe('authenticate should', () => {
44
56
  const rpcMock = mock<AuthenticationClient['Type']>()
45
57
 
46
58
  rpcMock.getAuthenticationOptions.mockReturnValue(E.succeed(Fixture.rpcOptionsRes))
47
- rpcMock.verifyAuthenticationCredential.mockReturnValue(E.succeed(Fixture.rpcVerificationRes))
59
+ rpcMock.verifyAuthenticationCredential.mockReturnValue(
60
+ E.succeed(Fixture.rpcVerificationRes),
61
+ )
48
62
 
49
63
  return rpcMock
50
64
  }),
@@ -67,11 +81,19 @@ describe('authenticate should', () => {
67
81
  test('send the credential to the backend', async () => {
68
82
  const assertions = E.gen(function* (_) {
69
83
  const service = yield* _(AuthenticationService)
70
- yield* _(service.authenticatePasskey({ userVerification: 'preferred' }))
84
+
85
+ yield* _(
86
+ service.authenticatePasskey({
87
+ email: O.none(),
88
+ userVerification: O.some('preferred'),
89
+ }),
90
+ )
71
91
 
72
92
  const rpcClient = yield* _(AuthenticationClient)
73
93
  expect(rpcClient.getAuthenticationOptions).toHaveBeenCalledOnce()
74
- expect(rpcClient.verifyAuthenticationCredential).toHaveBeenCalledWith(Fixture.rpcVerificationReq)
94
+ expect(rpcClient.verifyAuthenticationCredential).toHaveBeenCalledWith(
95
+ Fixture.rpcVerificationReq,
96
+ )
75
97
  })
76
98
 
77
99
  const rpcClientTest = L.effect(
@@ -80,7 +102,9 @@ describe('authenticate should', () => {
80
102
  const rpcMock = mock<AuthenticationClient['Type']>()
81
103
 
82
104
  rpcMock.getAuthenticationOptions.mockReturnValue(E.succeed(Fixture.rpcOptionsRes))
83
- rpcMock.verifyAuthenticationCredential.mockReturnValue(E.succeed(Fixture.rpcVerificationRes))
105
+ rpcMock.verifyAuthenticationCredential.mockReturnValue(
106
+ E.succeed(Fixture.rpcVerificationRes),
107
+ )
84
108
 
85
109
  return rpcMock
86
110
  }),
@@ -103,7 +127,13 @@ describe('authenticate should', () => {
103
127
  test('store the credential in local storage', async () => {
104
128
  const assertions = E.gen(function* (_) {
105
129
  const service = yield* _(AuthenticationService)
106
- yield* _(service.authenticatePasskey({ userVerification: 'preferred' }))
130
+
131
+ yield* _(
132
+ service.authenticatePasskey({
133
+ email: O.none(),
134
+ userVerification: O.some('preferred'),
135
+ }),
136
+ )
107
137
 
108
138
  const storageService = yield* _(StorageService)
109
139
  expect(storageService.storeToken).toHaveBeenCalledWith(Fixture.principal)
@@ -112,7 +142,7 @@ describe('authenticate should', () => {
112
142
  const storageServiceTest = L.effect(
113
143
  StorageService,
114
144
  E.sync(() => {
115
- const storageMock = mock<StorageService>()
145
+ const storageMock = mock<StorageService['Type']>()
116
146
 
117
147
  storageMock.storeToken.mockReturnValue(E.void)
118
148
  storageMock.clearExpiredToken.mockReturnValue(E.void)
@@ -138,7 +168,13 @@ describe('authenticate should', () => {
138
168
  test('schedule deletion of the local token', async () => {
139
169
  const assertions = E.gen(function* (_) {
140
170
  const service = yield* _(AuthenticationService)
141
- yield* _(service.authenticatePasskey({ userVerification: 'preferred' }))
171
+
172
+ yield* _(
173
+ service.authenticatePasskey({
174
+ email: O.none(),
175
+ userVerification: O.some('preferred'),
176
+ }),
177
+ )
142
178
 
143
179
  const storageService = yield* _(StorageService)
144
180
  expect(storageService.clearExpiredToken).toHaveBeenCalledWith('passkey')
@@ -147,7 +183,7 @@ describe('authenticate should', () => {
147
183
  const storageServiceTest = L.effect(
148
184
  StorageService,
149
185
  E.sync(() => {
150
- const storageMock = mock<StorageService>()
186
+ const storageMock = mock<StorageService['Type']>()
151
187
 
152
188
  storageMock.storeToken.mockReturnValue(E.void)
153
189
  storageMock.clearExpiredToken.mockReturnValue(E.void)
@@ -173,20 +209,26 @@ describe('authenticate should', () => {
173
209
  test("return an error if the browser can't create a credential", async () => {
174
210
  const assertions = E.gen(function* (_) {
175
211
  const service = yield* _(AuthenticationService)
176
- yield* _(service.authenticatePasskey({ userVerification: 'preferred' }))
177
212
 
178
- const getCredential = yield* _(GetCredential)
213
+ yield* _(
214
+ service.authenticatePasskey({
215
+ email: O.none(),
216
+ userVerification: O.some('preferred'),
217
+ }),
218
+ )
219
+
220
+ const { getCredential } = yield* _(GetCredential)
179
221
  expect(getCredential).toHaveBeenCalledOnce()
180
222
  })
181
223
 
182
224
  const getCredentialTest = L.effect(
183
225
  GetCredential,
184
226
  E.sync(() => {
185
- const getCredentialMock = vi.fn()
227
+ const getCredential = vi.fn()
186
228
 
187
- getCredentialMock.mockReturnValue(E.succeed(Fixture.credential))
229
+ getCredential.mockReturnValue(E.succeed(Fixture.credential))
188
230
 
189
- return getCredentialMock
231
+ return { getCredential }
190
232
  }),
191
233
  )
192
234
 
@@ -2,52 +2,51 @@
2
2
  * Passkey authentication effects
3
3
  */
4
4
  import {
5
- parseRequestOptionsFromJSON,
6
5
  type CredentialRequestOptionsJSON,
6
+ parseRequestOptionsFromJSON,
7
7
  } from '@github/webauthn-json/browser-ponyfill'
8
+ import { InternalBrowserError, type NotSupported } from '@passlock/shared/dist/error/error.js'
8
9
  import {
9
- InternalBrowserError,
10
- type NotSupported,
11
- } from '@passlock/shared/dist/error/error.js'
12
- import type { OptionsErrors, VerificationErrors } from '@passlock/shared/dist/rpc/authentication.js'
13
- import { AuthenticationClient, OptionsReq, VerificationReq } from '@passlock/shared/dist/rpc/authentication.js'
14
- import type {
15
- AuthenticationCredential,
16
- UserVerification,
17
- } from '@passlock/shared/dist/schema/passkey.js'
18
- import { Principal } from '@passlock/shared/dist/schema/principal.js'
10
+ type OptionsErrors,
11
+ type OptionsReq,
12
+ type VerificationErrors,
13
+ VerificationReq,
14
+ } from '@passlock/shared/dist/rpc/authentication.js'
15
+ import type { AuthenticationCredential } from '@passlock/shared/dist/schema/passkey.js'
16
+ import type { Principal } from '@passlock/shared/dist/schema/principal.js'
19
17
  import { Context, Effect as E, Layer, flow, pipe } from 'effect'
20
18
  import { Capabilities } from '../capabilities/capabilities.js'
19
+ import { AuthenticationClient } from '../rpc/authentication.js'
21
20
  import { StorageService } from '../storage/storage.js'
22
21
 
23
22
  /* Requests */
24
23
 
25
- export type AuthenticationRequest = {
26
- email?: string,
27
- userVerification?: UserVerification
28
- }
29
-
24
+ export type AuthenticationRequest = OptionsReq
30
25
  /* Errors */
31
26
 
32
27
  export type AuthenticationErrors = NotSupported | OptionsErrors | VerificationErrors
33
28
 
34
29
  /* Dependencies */
35
30
 
36
- export type GetCredential = (
37
- request: CredentialRequestOptions,
38
- ) => E.Effect<AuthenticationCredential, InternalBrowserError>
39
-
40
- export const GetCredential = Context.GenericTag<GetCredential>('@services/Get')
31
+ export class GetCredential extends Context.Tag('@services/GetCredential')<
32
+ GetCredential,
33
+ {
34
+ getCredential: (
35
+ request: CredentialRequestOptions,
36
+ ) => E.Effect<AuthenticationCredential, InternalBrowserError>
37
+ }
38
+ >() {}
41
39
 
42
40
  /* Service */
43
41
 
44
- export type AuthenticationService = {
45
- authenticatePasskey: (request: AuthenticationRequest) => E.Effect<Principal, AuthenticationErrors>
46
- }
47
-
48
- export const AuthenticationService = Context.GenericTag<AuthenticationService>(
49
- '@services/AuthenticationService',
50
- )
42
+ export class AuthenticationService extends Context.Tag('@services/AuthenticationService')<
43
+ AuthenticationService,
44
+ {
45
+ authenticatePasskey: (
46
+ request: AuthenticationRequest,
47
+ ) => E.Effect<Principal, AuthenticationErrors>
48
+ }
49
+ >() {}
51
50
 
52
51
  /* Utilities */
53
52
 
@@ -102,11 +101,12 @@ export const authenticatePasskey = (
102
101
  yield* _(capabilities.passkeySupport)
103
102
 
104
103
  yield* _(E.logInfo('Fetching authentication options from Passlock'))
105
- const { options, session } = yield* _(fetchOptions(new OptionsReq(request)))
104
+
105
+ const { options, session } = yield* _(fetchOptions(request))
106
106
 
107
107
  yield* _(E.logInfo('Looking up credential'))
108
- const get = yield* _(GetCredential)
109
- const credential = yield* _(get(options))
108
+ const { getCredential } = yield* _(GetCredential)
109
+ const credential = yield* _(getCredential(options))
110
110
 
111
111
  yield* _(E.logInfo('Verifying credential with Passlock'))
112
112
  const principal = yield* _(verifyCredential(new VerificationReq({ credential, session })))
@@ -135,7 +135,9 @@ export const authenticatePasskey = (
135
135
  export const AuthenticateServiceLive = Layer.effect(
136
136
  AuthenticationService,
137
137
  E.gen(function* (_) {
138
- const context = yield* _(E.context<GetCredential | AuthenticationClient | Capabilities | StorageService>())
138
+ const context = yield* _(
139
+ E.context<GetCredential | AuthenticationClient | Capabilities | StorageService>(),
140
+ )
139
141
 
140
142
  return AuthenticationService.of({
141
143
  authenticatePasskey: flow(authenticatePasskey, E.provide(context)),
@@ -6,14 +6,15 @@ import { Context, Effect as E, Layer, identity, pipe } from 'effect'
6
6
 
7
7
  /* Service */
8
8
 
9
- export type Capabilities = {
10
- passkeySupport: E.Effect<void, NotSupported>
11
- isPasskeySupport: E.Effect<boolean>
12
- autofillSupport: E.Effect<void, NotSupported>
13
- isAutofillSupport: E.Effect<boolean>
14
- }
15
-
16
- export const Capabilities = Context.GenericTag<Capabilities>('@services/Capabilities')
9
+ export class Capabilities extends Context.Tag('@services/Capabilities')<
10
+ Capabilities,
11
+ {
12
+ passkeySupport: E.Effect<void, NotSupported>
13
+ isPasskeySupport: E.Effect<boolean>
14
+ autofillSupport: E.Effect<void, NotSupported>
15
+ isAutofillSupport: E.Effect<boolean>
16
+ }
17
+ >() {}
17
18
 
18
19
  /* Effects */
19
20
 
@@ -1,5 +1,6 @@
1
- import { ConnectionClient, ConnectRes } from '@passlock/shared/dist/rpc/connection.js'
1
+ import { ConnectRes } from '@passlock/shared/dist/rpc/connection.js'
2
2
  import { Effect as E, Layer as L } from 'effect'
3
+ import { ConnectionClient } from '../rpc/connection.js'
3
4
 
4
5
  export const preConnectRes = new ConnectRes({ warmed: true })
5
6