@passlock/client 0.9.5 → 0.9.7

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 (91) hide show
  1. package/README.md +1 -1
  2. package/dist/authentication/authenticate.d.ts +6 -5
  3. package/dist/authentication/authenticate.d.ts.map +1 -1
  4. package/dist/authentication/authenticate.fixture.d.ts +8 -5
  5. package/dist/authentication/authenticate.fixture.d.ts.map +1 -1
  6. package/dist/authentication/authenticate.fixture.js +12 -7
  7. package/dist/authentication/authenticate.fixture.js.map +1 -1
  8. package/dist/authentication/authenticate.js +6 -6
  9. package/dist/authentication/authenticate.js.map +1 -1
  10. package/dist/authentication/authenticate.test.js +4 -4
  11. package/dist/capabilities/capabilities.js +3 -3
  12. package/dist/connection/connection.fixture.d.ts +1 -1
  13. package/dist/connection/connection.fixture.d.ts.map +1 -1
  14. package/dist/connection/connection.fixture.js +13 -10
  15. package/dist/connection/connection.fixture.js.map +1 -1
  16. package/dist/connection/connection.js +3 -3
  17. package/dist/effect.d.ts +21 -5
  18. package/dist/effect.d.ts.map +1 -1
  19. package/dist/effect.js +12 -9
  20. package/dist/effect.js.map +1 -1
  21. package/dist/email/email.d.ts +24 -8
  22. package/dist/email/email.d.ts.map +1 -1
  23. package/dist/email/email.fixture.d.ts +8 -8
  24. package/dist/email/email.fixture.d.ts.map +1 -1
  25. package/dist/email/email.fixture.js +12 -10
  26. package/dist/email/email.fixture.js.map +1 -1
  27. package/dist/email/email.js +5 -5
  28. package/dist/email/email.js.map +1 -1
  29. package/dist/email/email.test.js +4 -4
  30. package/dist/email/email.test.js.map +1 -1
  31. package/dist/index.d.ts +52 -37
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +21 -14
  34. package/dist/index.js.map +1 -1
  35. package/dist/registration/register.d.ts +3 -4
  36. package/dist/registration/register.d.ts.map +1 -1
  37. package/dist/registration/register.fixture.d.ts +4 -4
  38. package/dist/registration/register.fixture.d.ts.map +1 -1
  39. package/dist/registration/register.fixture.js +12 -8
  40. package/dist/registration/register.fixture.js.map +1 -1
  41. package/dist/registration/register.js +4 -13
  42. package/dist/registration/register.js.map +1 -1
  43. package/dist/social/social.d.ts +22 -0
  44. package/dist/social/social.d.ts.map +1 -0
  45. package/dist/social/social.js +29 -0
  46. package/dist/social/social.js.map +1 -0
  47. package/dist/storage/storage.d.ts +1 -1
  48. package/dist/storage/storage.d.ts.map +1 -1
  49. package/dist/storage/storage.fixture.d.ts +1 -2
  50. package/dist/storage/storage.fixture.d.ts.map +1 -1
  51. package/dist/storage/storage.fixture.js +1 -16
  52. package/dist/storage/storage.fixture.js.map +1 -1
  53. package/dist/storage/storage.js +4 -3
  54. package/dist/storage/storage.js.map +1 -1
  55. package/dist/test/fixtures.d.ts +4 -0
  56. package/dist/test/fixtures.d.ts.map +1 -1
  57. package/dist/test/fixtures.js +13 -9
  58. package/dist/test/fixtures.js.map +1 -1
  59. package/dist/user/user.d.ts +9 -2
  60. package/dist/user/user.d.ts.map +1 -1
  61. package/dist/user/user.fixture.d.ts +3 -2
  62. package/dist/user/user.fixture.d.ts.map +1 -1
  63. package/dist/user/user.fixture.js +13 -9
  64. package/dist/user/user.fixture.js.map +1 -1
  65. package/dist/user/user.js +11 -1
  66. package/dist/user/user.js.map +1 -1
  67. package/package.json +15 -14
  68. package/src/authentication/authenticate.fixture.ts +14 -7
  69. package/src/authentication/authenticate.test.ts +4 -4
  70. package/src/authentication/authenticate.ts +15 -12
  71. package/src/capabilities/capabilities.ts +3 -3
  72. package/src/connection/connection.fixture.ts +14 -11
  73. package/src/connection/connection.ts +4 -4
  74. package/src/effect.ts +28 -26
  75. package/src/email/email.fixture.ts +15 -13
  76. package/src/email/email.test.ts +4 -4
  77. package/src/email/email.ts +13 -12
  78. package/src/index.ts +91 -34
  79. package/src/registration/register.fixture.ts +12 -8
  80. package/src/registration/register.test.ts +8 -43
  81. package/src/registration/register.ts +8 -24
  82. package/src/social/social.ts +86 -0
  83. package/src/storage/storage.fixture.ts +2 -19
  84. package/src/storage/storage.ts +5 -4
  85. package/src/test/fixtures.ts +15 -10
  86. package/src/user/user.fixture.ts +14 -11
  87. package/src/user/user.ts +22 -3
  88. package/dist/exit.d.ts +0 -64
  89. package/dist/exit.d.ts.map +0 -1
  90. package/dist/exit.js +0 -106
  91. package/dist/exit.js.map +0 -1
@@ -6,11 +6,10 @@ import {
6
6
  parseRequestOptionsFromJSON,
7
7
  } from '@github/webauthn-json/browser-ponyfill'
8
8
  import {
9
- type BadRequest,
10
9
  InternalBrowserError,
11
10
  type NotSupported,
12
11
  } from '@passlock/shared/dist/error/error.js'
13
- import type { VerificationErrors } from '@passlock/shared/dist/rpc/authentication.js'
12
+ import type { OptionsErrors, VerificationErrors } from '@passlock/shared/dist/rpc/authentication.js'
14
13
  import { OptionsReq, VerificationReq } from '@passlock/shared/dist/rpc/authentication.js'
15
14
  import { RpcClient } from '@passlock/shared/dist/rpc/rpc.js'
16
15
  import type {
@@ -24,23 +23,27 @@ import { StorageService } from '../storage/storage.js'
24
23
 
25
24
  /* Requests */
26
25
 
27
- export type AuthenticationRequest = { userVerification?: UserVerification }
26
+ export type AuthenticationRequest = {
27
+ email?: string,
28
+ userVerification?: UserVerification
29
+ }
28
30
 
29
31
  /* Errors */
30
32
 
31
- export type AuthenticationErrors = NotSupported | BadRequest | VerificationErrors
33
+ export type AuthenticationErrors = NotSupported | OptionsErrors | VerificationErrors
32
34
 
33
35
  /* Dependencies */
34
36
 
35
37
  export type GetCredential = (
36
- options: CredentialRequestOptions,
38
+ request: CredentialRequestOptions,
37
39
  ) => E.Effect<AuthenticationCredential, InternalBrowserError>
40
+
38
41
  export const GetCredential = Context.GenericTag<GetCredential>('@services/Get')
39
42
 
40
43
  /* Service */
41
44
 
42
45
  export type AuthenticationService = {
43
- authenticatePasskey: (data: AuthenticationRequest) => E.Effect<Principal, AuthenticationErrors>
46
+ authenticatePasskey: (request: AuthenticationRequest) => E.Effect<Principal, AuthenticationErrors>
44
47
  }
45
48
 
46
49
  export const AuthenticationService = Context.GenericTag<AuthenticationService>(
@@ -49,12 +52,12 @@ export const AuthenticationService = Context.GenericTag<AuthenticationService>(
49
52
 
50
53
  /* Utilities */
51
54
 
52
- const fetchOptions = (req: OptionsReq) => {
55
+ const fetchOptions = (request: OptionsReq) => {
53
56
  return E.gen(function* (_) {
54
57
  yield* _(E.logDebug('Making request'))
55
58
 
56
59
  const rpcClient = yield* _(RpcClient)
57
- const { publicKey, session } = yield* _(rpcClient.getAuthenticationOptions(req))
60
+ const { publicKey, session } = yield* _(rpcClient.getAuthenticationOptions(request))
58
61
 
59
62
  yield* _(E.logDebug('Converting Passlock options to CredentialRequestOptions'))
60
63
  const options = yield* _(toRequestOptions({ publicKey }))
@@ -63,9 +66,9 @@ const fetchOptions = (req: OptionsReq) => {
63
66
  })
64
67
  }
65
68
 
66
- const toRequestOptions = (options: CredentialRequestOptionsJSON) => {
69
+ const toRequestOptions = (request: CredentialRequestOptionsJSON) => {
67
70
  return pipe(
68
- E.try(() => parseRequestOptionsFromJSON(options)),
71
+ E.try(() => parseRequestOptionsFromJSON(request)),
69
72
  E.mapError(
70
73
  error =>
71
74
  new InternalBrowserError({
@@ -76,12 +79,12 @@ const toRequestOptions = (options: CredentialRequestOptionsJSON) => {
76
79
  )
77
80
  }
78
81
 
79
- const verifyCredential = (req: VerificationReq) => {
82
+ const verifyCredential = (request: VerificationReq) => {
80
83
  return E.gen(function* (_) {
81
84
  yield* _(E.logDebug('Making request'))
82
85
 
83
86
  const rpcClient = yield* _(RpcClient)
84
- const { principal } = yield* _(rpcClient.verifyAuthenticationCredential(req))
87
+ const { principal } = yield* _(rpcClient.verifyAuthenticationCredential(request))
85
88
 
86
89
  return principal
87
90
  })
@@ -19,7 +19,7 @@ export const Capabilities = Context.GenericTag<Capabilities>('@services/Capabili
19
19
 
20
20
  const hasWebAuthn = E.suspend(() =>
21
21
  typeof window.PublicKeyCredential === 'function'
22
- ? E.unit
22
+ ? E.void
23
23
  : new NotSupported({ message: 'WebAuthn API is not supported on this device' }),
24
24
  )
25
25
 
@@ -29,7 +29,7 @@ const hasPlatformAuth = pipe(
29
29
  identity,
30
30
  () => new NotSupported({ message: 'No platform authenticator available on this device' }),
31
31
  ),
32
- E.asUnit,
32
+ E.asVoid,
33
33
  )
34
34
 
35
35
  const hasConditionalUi = pipe(
@@ -42,7 +42,7 @@ const hasConditionalUi = pipe(
42
42
  identity,
43
43
  () => new NotSupported({ message: 'Conditional mediation not available on this device' }),
44
44
  ),
45
- E.asUnit,
45
+ E.asVoid,
46
46
  )
47
47
 
48
48
  export const passkeySupport = pipe(
@@ -1,24 +1,27 @@
1
- import { BadRequest } from '@passlock/shared/dist/error/error.js'
2
1
  import { PreConnectReq, PreConnectRes } from '@passlock/shared/dist/rpc/connection.js'
3
2
  import { RpcClient } from '@passlock/shared/dist/rpc/rpc.js'
4
3
  import { Effect as E, Layer as L } from 'effect'
4
+ import * as Fixtures from '../test/fixtures.js'
5
+
6
+ export const preConnectReq = new PreConnectReq({})
7
+ export const preConnectRes = new PreConnectRes({ warmed: true })
5
8
 
6
9
  export const rpcClientTest = L.succeed(
7
10
  RpcClient,
8
11
  RpcClient.of({
9
- preConnect: () => E.succeed({ warmed: true }),
10
- isExistingUser: () => E.succeed({ existingUser: true }),
11
- verifyEmail: () => E.succeed({ verified: true }),
12
- getRegistrationOptions: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
13
- verifyRegistrationCredential: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
14
- getAuthenticationOptions: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
15
- verifyAuthenticationCredential: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
12
+ preConnect: () => E.succeed(preConnectRes),
13
+ isExistingUser: () => E.fail(Fixtures.notImplemented),
14
+ verifyEmail: () => E.fail(Fixtures.notImplemented),
15
+ getRegistrationOptions: () => E.fail(Fixtures.notImplemented),
16
+ verifyRegistrationCredential: () => E.fail(Fixtures.notImplemented),
17
+ getAuthenticationOptions: () => E.fail(Fixtures.notImplemented),
18
+ verifyAuthenticationCredential: () => E.fail(Fixtures.notImplemented),
19
+ registerOidc: () => E.fail(Fixtures.notImplemented),
20
+ authenticateOidc: () => E.fail(Fixtures.notImplemented),
21
+ resendVerificationEmail: () => E.fail(Fixtures.notImplemented),
16
22
  }),
17
23
  )
18
24
 
19
- export const preConnectReq = new PreConnectReq({})
20
- export const preConnectRes = new PreConnectRes({ warmed: true })
21
-
22
25
  export const rpcConfig = {
23
26
  endpoint: 'https://example.com',
24
27
  tenancyId: 'tenancyId',
@@ -20,18 +20,18 @@ const hitPrincipal = pipe(
20
20
  E.logInfo('Pre-connecting to Principal endpoint'),
21
21
  E.zipRight(Dispatcher),
22
22
  E.flatMap(dispatcher => dispatcher.get('/token/token?warm=true')),
23
- E.asUnit,
24
- E.catchAll(() => E.unit),
23
+ E.asVoid,
24
+ E.catchAll(() => E.void),
25
25
  )
26
26
 
27
27
  const hitRpc = pipe(
28
28
  E.logInfo('Pre-connecting to RPC endpoint'),
29
29
  E.zipRight(RpcClient),
30
30
  E.flatMap(rpcClient => rpcClient.preConnect(new PreConnectReq({}))),
31
- E.asUnit,
31
+ E.asVoid,
32
32
  )
33
33
 
34
- export const preConnect = () => pipe(E.all([hitPrincipal, hitRpc], { concurrency: 2 }), E.asUnit)
34
+ export const preConnect = () => pipe(E.all([hitPrincipal, hitRpc], { concurrency: 2 }), E.asVoid)
35
35
 
36
36
  /* Live */
37
37
 
package/src/effect.ts CHANGED
@@ -1,18 +1,5 @@
1
1
  import { create, get as getCredential } from '@github/webauthn-json/browser-ponyfill'
2
2
 
3
- export type {
4
- BadRequest,
5
- Disabled,
6
- Duplicate,
7
- Forbidden,
8
- InternalBrowserError,
9
- NotFound,
10
- NotSupported,
11
- Unauthorized,
12
- } from '@passlock/shared/dist/error/error.js'
13
-
14
- export type { Principal } from '@passlock/shared/dist/schema/schema.js'
15
-
16
3
  import {
17
4
  type BadRequest,
18
5
  type Disabled,
@@ -32,6 +19,7 @@ import {
32
19
  } from '@passlock/shared/dist/rpc/rpc.js'
33
20
 
34
21
  import type { Principal } from '@passlock/shared/dist/schema/schema.js'
22
+
35
23
  import { Context, Effect as E, Layer as L, Layer, Schedule, pipe } from 'effect'
36
24
  import type { NoSuchElementException } from 'effect/Cause'
37
25
 
@@ -44,7 +32,7 @@ import {
44
32
 
45
33
  import { capabilitiesLive } from './capabilities/capabilities.js'
46
34
  import { ConnectionService, ConnectionServiceLive } from './connection/connection.js'
47
- import { EmailService, EmailServiceLive, LocationSearch, type VerifyRequest } from './email/email.js'
35
+ import { EmailService, EmailServiceLive, URLQueryString, type VerifyRequest } from './email/email.js'
48
36
 
49
37
  import {
50
38
  CreateCredential,
@@ -62,10 +50,11 @@ import {
62
50
  } from './storage/storage.js'
63
51
 
64
52
  import { type Email, UserService, UserServiceLive } from './user/user.js'
53
+ import { SocialService, SocialServiceLive, type OidcRequest } from './social/social.js'
65
54
 
66
55
  /* Layers */
67
56
 
68
- const createLive = L.succeed(
57
+ const createCredentialLive = L.succeed(
69
58
  CreateCredential,
70
59
  CreateCredential.of((options: CredentialCreationOptions) =>
71
60
  pipe(
@@ -74,7 +63,7 @@ const createLive = L.succeed(
74
63
  catch: e => {
75
64
  if (e instanceof Error && e.message.includes('excludeCredentials')) {
76
65
  return new Duplicate({
77
- message: 'Passkey already registered on this device or cloud account',
66
+ message: 'Passkey already registered to this device or cloud account',
78
67
  })
79
68
  } else {
80
69
  return new InternalBrowserError({
@@ -84,12 +73,12 @@ const createLive = L.succeed(
84
73
  }
85
74
  },
86
75
  }),
87
- E.map(credential => credential.toJSON()),
76
+ E.map(credential => credential.toJSON())
88
77
  ),
89
78
  ),
90
79
  )
91
80
 
92
- const getLive = L.succeed(
81
+ const getCredentialLive = L.succeed(
93
82
  GetCredential,
94
83
  GetCredential.of((options: CredentialRequestOptions) =>
95
84
  pipe(
@@ -123,7 +112,7 @@ const registrationServiceLive = pipe(
123
112
  L.provide(rpcClientLive),
124
113
  L.provide(userServiceLive),
125
114
  L.provide(capabilitiesLive),
126
- L.provide(createLive),
115
+ L.provide(createCredentialLive),
127
116
  L.provide(storageServiceLive),
128
117
  )
129
118
 
@@ -131,7 +120,7 @@ const authenticationServiceLive = pipe(
131
120
  AuthenticateServiceLive,
132
121
  L.provide(rpcClientLive),
133
122
  L.provide(capabilitiesLive),
134
- L.provide(getLive),
123
+ L.provide(getCredentialLive),
135
124
  L.provide(storageServiceLive),
136
125
  )
137
126
 
@@ -141,20 +130,25 @@ const connectionServiceLive = pipe(
141
130
  L.provide(dispatcherLive),
142
131
  )
143
132
 
144
- const locationSearchLive = Layer.succeed(
145
- LocationSearch,
146
- LocationSearch.of(E.sync(() => globalThis.window.location.search)),
133
+ const urlQueryStringLive = Layer.succeed(
134
+ URLQueryString,
135
+ URLQueryString.of(E.sync(() => globalThis.window.location.search)),
147
136
  )
148
137
 
149
138
  const emailServiceLive = pipe(
150
139
  EmailServiceLive,
151
- L.provide(locationSearchLive),
140
+ L.provide(urlQueryStringLive),
152
141
  L.provide(rpcClientLive),
153
142
  L.provide(capabilitiesLive),
154
143
  L.provide(authenticationServiceLive),
155
144
  L.provide(storageServiceLive),
156
145
  )
157
146
 
147
+ const socialServiceLive = pipe(
148
+ SocialServiceLive,
149
+ L.provide(rpcClientLive),
150
+ )
151
+
158
152
  export const allRequirements = Layer.mergeAll(
159
153
  capabilitiesLive,
160
154
  userServiceLive,
@@ -163,6 +157,7 @@ export const allRequirements = Layer.mergeAll(
163
157
  connectionServiceLive,
164
158
  emailServiceLive,
165
159
  storageServiceLive,
160
+ socialServiceLive,
166
161
  )
167
162
 
168
163
  export class Config extends Context.Tag('Config')<
@@ -243,7 +238,7 @@ export type VerifyEmailErrors =
243
238
 
244
239
  export const verifyEmailCode = (
245
240
  request: VerifyRequest,
246
- ): E.Effect<boolean, VerifyEmailErrors, Config> =>
241
+ ): E.Effect<Principal, VerifyEmailErrors, Config> =>
247
242
  pipe(
248
243
  EmailService,
249
244
  E.flatMap(service => service.verifyEmailCode(request)),
@@ -251,7 +246,7 @@ export const verifyEmailCode = (
251
246
  exchangeConfig,
252
247
  )
253
248
 
254
- export const verifyEmailLink = (): E.Effect<boolean, VerifyEmailErrors, Config> =>
249
+ export const verifyEmailLink = (): E.Effect<Principal, VerifyEmailErrors, Config> =>
255
250
  pipe(
256
251
  EmailService,
257
252
  E.flatMap(service => service.verifyEmailLink()),
@@ -276,3 +271,10 @@ export const clearExpiredTokens = (): E.Effect<void> =>
276
271
  E.provide(storageServiceLive),
277
272
  E.provide(storageLive),
278
273
  )
274
+
275
+ export const authenticateOIDC = (request: OidcRequest) =>
276
+ pipe(
277
+ SocialService,
278
+ E.flatMap(service => service.registerOidc(request)),
279
+ E.provide(socialServiceLive)
280
+ )
@@ -1,8 +1,7 @@
1
- import { BadRequest } from '@passlock/shared/dist/error/error.js'
2
1
  import { RpcClient } from '@passlock/shared/dist/rpc/rpc.js'
3
2
  import { VerifyEmailReq, VerifyEmailRes } from '@passlock/shared/dist/rpc/user.js'
4
3
  import { Effect as E, Layer as L } from 'effect'
5
- import { LocationSearch } from './email.js'
4
+ import { URLQueryString } from './email.js'
6
5
  import { AuthenticationService } from '../authentication/authenticate.js'
7
6
  import * as Fixtures from '../test/fixtures.js'
8
7
 
@@ -12,8 +11,8 @@ export const authType = 'passkey'
12
11
  export const expireAt = Date.now() + 10000
13
12
 
14
13
  export const locationSearchTest = L.succeed(
15
- LocationSearch,
16
- LocationSearch.of(E.succeed(`?code=${code}`)),
14
+ URLQueryString,
15
+ URLQueryString.of(E.succeed(`?code=${code}`)),
17
16
  )
18
17
 
19
18
  export const authenticationServiceTest = L.succeed(
@@ -23,23 +22,26 @@ export const authenticationServiceTest = L.succeed(
23
22
  }),
24
23
  )
25
24
 
25
+ export const verifyEmailReq = new VerifyEmailReq({ token, code })
26
+
27
+ export const verifyEmailRes = new VerifyEmailRes({ principal: Fixtures.principal })
28
+
26
29
  export const rpcClientTest = L.succeed(
27
30
  RpcClient,
28
31
  RpcClient.of({
29
32
  preConnect: () => E.succeed({ warmed: true }),
30
33
  isExistingUser: () => E.succeed({ existingUser: true }),
31
- verifyEmail: () => E.succeed({ verified: true }),
32
- getRegistrationOptions: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
33
- verifyRegistrationCredential: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
34
- getAuthenticationOptions: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
35
- verifyAuthenticationCredential: () => E.fail(new BadRequest({ message: 'Not implemeneted' })),
34
+ verifyEmail: () => E.succeed(verifyEmailRes),
35
+ getRegistrationOptions: () => E.fail(Fixtures.notImplemented),
36
+ verifyRegistrationCredential: () => E.fail(Fixtures.notImplemented),
37
+ getAuthenticationOptions: () => E.fail(Fixtures.notImplemented),
38
+ verifyAuthenticationCredential: () => E.fail(Fixtures.notImplemented),
39
+ registerOidc: () => E.fail(Fixtures.notImplemented),
40
+ authenticateOidc: () => E.fail(Fixtures.notImplemented),
41
+ resendVerificationEmail: () => E.fail(Fixtures.notImplemented),
36
42
  }),
37
43
  )
38
44
 
39
- export const verifyEmailReq = new VerifyEmailReq({ token, code })
40
-
41
- export const verifyEmailRes = new VerifyEmailRes({ verified: true })
42
-
43
45
  export const principal = Fixtures.principal
44
46
 
45
47
  export const storedToken = Fixtures.storedToken
@@ -9,12 +9,12 @@ import { AuthenticationService } from '../authentication/authenticate.js'
9
9
  import { StorageService } from '../storage/storage.js'
10
10
 
11
11
  describe('verifyEmailCode should', () => {
12
- test('return true when the verification is successful', async () => {
12
+ test('return a principal when the verification is successful', async () => {
13
13
  const assertions = E.gen(function* (_) {
14
14
  const service = yield* _(EmailService)
15
15
  const result = yield* _(service.verifyEmailCode({ code: '123' }))
16
16
 
17
- expect(result).toBe(true)
17
+ expect(result).toEqual(Fixture.principal)
18
18
  })
19
19
 
20
20
  const service = pipe(
@@ -45,7 +45,7 @@ describe('verifyEmailCode should', () => {
45
45
  const storageServiceMock = mock<StorageService>()
46
46
 
47
47
  storageServiceMock.getToken.mockReturnValue(E.succeed(Fixture.storedToken))
48
- storageServiceMock.clearToken.mockReturnValue(E.unit)
48
+ storageServiceMock.clearToken.mockReturnValue(E.void)
49
49
 
50
50
  return storageServiceMock
51
51
  }),
@@ -80,7 +80,7 @@ describe('verifyEmailCode should', () => {
80
80
  const storageServiceMock = mock<StorageService>()
81
81
 
82
82
  storageServiceMock.getToken.mockReturnValue(E.fail(new NoSuchElementException()))
83
- storageServiceMock.clearToken.mockReturnValue(E.unit)
83
+ storageServiceMock.clearToken.mockReturnValue(E.void)
84
84
 
85
85
  return storageServiceMock
86
86
  }),
@@ -8,6 +8,7 @@ import { VerifyEmailReq } from '@passlock/shared/dist/rpc/user.js'
8
8
  import { Context, Effect as E, Layer, Option as O, flow, identity, pipe } from 'effect'
9
9
  import { type AuthenticationErrors, AuthenticationService } from '../authentication/authenticate.js'
10
10
  import { StorageService } from '../storage/storage.js'
11
+ import type { Principal } from '@passlock/shared/dist/schema/schema.js'
11
12
 
12
13
  /* Requests */
13
14
 
@@ -21,16 +22,16 @@ export type VerifyEmailErrors = RpcErrors | AuthenticationErrors
21
22
 
22
23
  /* Dependencies */
23
24
 
24
- export class LocationSearch extends Context.Tag('LocationSearch')<
25
- LocationSearch,
25
+ export class URLQueryString extends Context.Tag('URLQueryString')<
26
+ URLQueryString,
26
27
  E.Effect<string>
27
28
  >() {}
28
29
 
29
30
  /* Service */
30
31
 
31
32
  export type EmailService = {
32
- verifyEmailCode: (request: VerifyRequest) => E.Effect<boolean, VerifyEmailErrors>
33
- verifyEmailLink: () => E.Effect<boolean, VerifyEmailErrors>
33
+ verifyEmailCode: (request: VerifyRequest) => E.Effect<Principal, VerifyEmailErrors>
34
+ verifyEmailLink: () => E.Effect<Principal, VerifyEmailErrors>
34
35
  }
35
36
 
36
37
  export const EmailService = Context.GenericTag<EmailService>('@services/EmailService')
@@ -78,7 +79,7 @@ const getToken = () => {
78
79
  */
79
80
  export const extractCodeFromHref = () => {
80
81
  return pipe(
81
- LocationSearch,
82
+ URLQueryString,
82
83
  E.flatMap(identity),
83
84
  E.map(search => new URLSearchParams(search)),
84
85
  E.flatMap(params => O.fromNullable(params.get('code'))),
@@ -89,23 +90,23 @@ export const extractCodeFromHref = () => {
89
90
 
90
91
  /**
91
92
  * Verify the mailbox using the given code
92
- * @param verificationRequest
93
+ * @param request
93
94
  * @returns
94
95
  */
95
96
  export const verifyEmail = (
96
- verificationRequest: VerifyRequest,
97
- ): E.Effect<boolean, VerifyEmailErrors, Dependencies> => {
97
+ request: VerifyRequest,
98
+ ): E.Effect<Principal, VerifyEmailErrors, Dependencies> => {
98
99
  return E.gen(function* (_) {
99
100
  // Re-authenticate the user if required
100
101
  const { token } = yield* _(getToken())
101
102
 
102
103
  yield* _(E.logDebug('Making request'))
103
104
  const client = yield* _(RpcClient)
104
- const { verified } = yield* _(
105
- client.verifyEmail(new VerifyEmailReq({ token, code: verificationRequest.code })),
105
+ const { principal } = yield* _(
106
+ client.verifyEmail(new VerifyEmailReq({ token, code: request.code })),
106
107
  )
107
108
 
108
- return verified
109
+ return principal
109
110
  })
110
111
  }
111
112
 
@@ -127,7 +128,7 @@ export const EmailServiceLive = Layer.effect(
127
128
  EmailService,
128
129
  E.gen(function* (_) {
129
130
  const context = yield* _(
130
- E.context<RpcClient | AuthenticationService | StorageService | LocationSearch>(),
131
+ E.context<RpcClient | AuthenticationService | StorageService | URLQueryString>(),
131
132
  )
132
133
  return EmailService.of({
133
134
  verifyEmailCode: flow(verifyEmail, E.provide(context)),