@passlock/client 0.9.19 → 0.9.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authentication/authenticate.d.ts +5 -4
- package/dist/authentication/authenticate.d.ts.map +1 -1
- package/dist/authentication/authenticate.fixture.d.ts +3 -4
- package/dist/authentication/authenticate.fixture.d.ts.map +1 -1
- package/dist/authentication/authenticate.fixture.js +2 -11
- package/dist/authentication/authenticate.fixture.js.map +1 -1
- package/dist/authentication/authenticate.js +4 -4
- package/dist/authentication/authenticate.js.map +1 -1
- package/dist/authentication/authenticate.test.js +5 -5
- package/dist/authentication/authenticate.test.js.map +1 -1
- package/dist/connection/connection.d.ts +4 -3
- package/dist/connection/connection.d.ts.map +1 -1
- package/dist/connection/connection.fixture.d.ts +3 -5
- package/dist/connection/connection.fixture.d.ts.map +1 -1
- package/dist/connection/connection.fixture.js +3 -15
- package/dist/connection/connection.fixture.js.map +1 -1
- package/dist/connection/connection.js +3 -3
- package/dist/connection/connection.js.map +1 -1
- package/dist/connection/connection.test.js +6 -5
- package/dist/connection/connection.test.js.map +1 -1
- package/dist/effect.d.ts +1 -1
- package/dist/effect.d.ts.map +1 -1
- package/dist/effect.js +17 -8
- package/dist/effect.js.map +1 -1
- package/dist/email/email.d.ts +4 -4
- package/dist/email/email.d.ts.map +1 -1
- package/dist/email/email.fixture.d.ts +2 -3
- package/dist/email/email.fixture.d.ts.map +1 -1
- package/dist/email/email.fixture.js +2 -10
- package/dist/email/email.fixture.js.map +1 -1
- package/dist/email/email.js +2 -3
- package/dist/email/email.js.map +1 -1
- package/dist/email/email.test.js +5 -5
- package/dist/email/email.test.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/eventLogger.d.ts.map +1 -1
- package/dist/logging/eventLogger.js +15 -9
- package/dist/logging/eventLogger.js.map +1 -1
- package/dist/logging/eventLogger.test.js.map +1 -1
- package/dist/registration/register.d.ts +6 -4
- package/dist/registration/register.d.ts.map +1 -1
- package/dist/registration/register.fixture.d.ts +3 -4
- package/dist/registration/register.fixture.d.ts.map +1 -1
- package/dist/registration/register.fixture.js +2 -12
- package/dist/registration/register.fixture.js.map +1 -1
- package/dist/registration/register.js +5 -4
- package/dist/registration/register.js.map +1 -1
- package/dist/registration/register.test.js +6 -6
- package/dist/registration/register.test.js.map +1 -1
- package/dist/rpc/authentication.d.ts +9 -0
- package/dist/rpc/authentication.d.ts.map +1 -0
- package/dist/rpc/authentication.js +15 -0
- package/dist/rpc/authentication.js.map +1 -0
- package/dist/rpc/client.d.ts +27 -0
- package/dist/rpc/client.d.ts.map +1 -0
- package/dist/rpc/client.js +92 -0
- package/dist/rpc/client.js.map +1 -0
- package/dist/rpc/config.d.ts +16 -0
- package/dist/rpc/config.d.ts.map +1 -0
- package/dist/rpc/config.js +6 -0
- package/dist/rpc/config.js.map +1 -0
- package/dist/rpc/connection.d.ts +9 -0
- package/dist/rpc/connection.d.ts.map +1 -0
- package/dist/rpc/connection.js +14 -0
- package/dist/rpc/connection.js.map +1 -0
- package/dist/rpc/registration.d.ts +9 -0
- package/dist/rpc/registration.d.ts.map +1 -0
- package/dist/rpc/registration.js +15 -0
- package/dist/rpc/registration.js.map +1 -0
- package/dist/rpc/social.d.ts +11 -0
- package/dist/rpc/social.d.ts.map +1 -0
- package/dist/rpc/social.js +17 -0
- package/dist/rpc/social.js.map +1 -0
- package/dist/rpc/user.d.ts +9 -0
- package/dist/rpc/user.d.ts.map +1 -0
- package/dist/rpc/user.js +18 -0
- package/dist/rpc/user.js.map +1 -0
- package/dist/social/social.d.ts +4 -4
- package/dist/social/social.d.ts.map +1 -1
- package/dist/social/social.fixture.d.ts +1 -2
- package/dist/social/social.fixture.d.ts.map +1 -1
- package/dist/social/social.fixture.js +5 -14
- package/dist/social/social.fixture.js.map +1 -1
- package/dist/social/social.js +6 -6
- package/dist/social/social.js.map +1 -1
- package/dist/social/social.test.js +9 -9
- package/dist/social/social.test.js.map +1 -1
- package/dist/storage/storage.d.ts +1 -1
- package/dist/storage/storage.d.ts.map +1 -1
- package/dist/test/fixtures.d.ts +1 -3
- package/dist/test/fixtures.d.ts.map +1 -1
- package/dist/test/fixtures.js +0 -2
- package/dist/test/fixtures.js.map +1 -1
- package/dist/user/user.d.ts +4 -4
- package/dist/user/user.d.ts.map +1 -1
- package/dist/user/user.fixture.d.ts +2 -3
- package/dist/user/user.fixture.d.ts.map +1 -1
- package/dist/user/user.fixture.js +2 -10
- package/dist/user/user.fixture.js.map +1 -1
- package/dist/user/user.js +3 -4
- package/dist/user/user.js.map +1 -1
- package/dist/user/user.test.js +5 -5
- package/dist/user/user.test.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +10 -11
- package/src/authentication/authenticate.fixture.ts +8 -16
- package/src/authentication/authenticate.test.ts +7 -7
- package/src/authentication/authenticate.ts +13 -14
- package/src/connection/connection.fixture.ts +4 -16
- package/src/connection/connection.test.ts +7 -6
- package/src/connection/connection.ts +5 -5
- package/src/effect.ts +20 -14
- package/src/email/email.fixture.ts +3 -11
- package/src/email/email.test.ts +7 -7
- package/src/email/email.ts +5 -6
- package/src/index.ts +5 -2
- package/src/logging/eventLogger.test.ts +1 -0
- package/src/logging/eventLogger.ts +16 -10
- package/src/registration/register.fixture.ts +9 -18
- package/src/registration/register.test.ts +9 -9
- package/src/registration/register.ts +12 -13
- package/src/social/social.fixture.ts +7 -16
- package/src/social/social.test.ts +15 -15
- package/src/social/social.ts +9 -9
- package/src/storage/storage.ts +1 -1
- package/src/test/fixtures.ts +1 -3
- package/src/user/user.fixture.ts +3 -11
- package/src/user/user.test.ts +7 -7
- package/src/user/user.ts +6 -7
- package/README.md +0 -116
package/src/email/email.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UserClient } from '@passlock/shared/dist/rpc/user.js'
|
|
2
2
|
import { Effect as E, Layer as L, LogLevel, Logger, pipe } from 'effect'
|
|
3
3
|
import { NoSuchElementException } from 'effect/Cause'
|
|
4
4
|
import { describe, expect, test } from 'vitest'
|
|
@@ -116,14 +116,14 @@ describe('verifyEmailCode should', () => {
|
|
|
116
116
|
const service = yield* _(EmailService)
|
|
117
117
|
yield* _(service.verifyEmailCode({ code: Fixture.code }))
|
|
118
118
|
|
|
119
|
-
const rpcClient = yield* _(
|
|
119
|
+
const rpcClient = yield* _(UserClient)
|
|
120
120
|
expect(rpcClient.verifyEmail).toHaveBeenCalledWith(Fixture.rpcVerifyEmailReq)
|
|
121
121
|
})
|
|
122
122
|
|
|
123
123
|
const rpcClientTest = L.effect(
|
|
124
|
-
|
|
124
|
+
UserClient,
|
|
125
125
|
E.sync(() => {
|
|
126
|
-
const rpcMock = mock<
|
|
126
|
+
const rpcMock = mock<UserClient['Type']>()
|
|
127
127
|
|
|
128
128
|
rpcMock.verifyEmail.mockReturnValue(E.succeed(Fixture.rpcVerifyEmailRes))
|
|
129
129
|
|
|
@@ -154,14 +154,14 @@ describe('verifyEmailLink should', () => {
|
|
|
154
154
|
|
|
155
155
|
// LocationSearch return ?code=code
|
|
156
156
|
// and we expect rpcClient to be called with code
|
|
157
|
-
const rpcClient = yield* _(
|
|
157
|
+
const rpcClient = yield* _(UserClient)
|
|
158
158
|
expect(rpcClient.verifyEmail).toBeCalledWith(Fixture.rpcVerifyEmailReq)
|
|
159
159
|
})
|
|
160
160
|
|
|
161
161
|
const rpcClientTest = L.effect(
|
|
162
|
-
|
|
162
|
+
UserClient,
|
|
163
163
|
E.sync(() => {
|
|
164
|
-
const rpcMock = mock<
|
|
164
|
+
const rpcMock = mock<UserClient['Type']>()
|
|
165
165
|
|
|
166
166
|
rpcMock.verifyEmail.mockReturnValue(E.succeed(Fixture.rpcVerifyEmailRes))
|
|
167
167
|
|
package/src/email/email.ts
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Email verification effects
|
|
3
3
|
*/
|
|
4
4
|
import { BadRequest } from '@passlock/shared/dist/error/error.js'
|
|
5
|
-
import { RpcClient } from '@passlock/shared/dist/rpc/rpc.js'
|
|
6
5
|
import type { VerifyEmailErrors as RpcErrors } from '@passlock/shared/dist/rpc/user.js'
|
|
7
|
-
import { VerifyEmailReq } from '@passlock/shared/dist/rpc/user.js'
|
|
8
|
-
import type { Principal } from '@passlock/shared/dist/schema/
|
|
6
|
+
import { UserClient, VerifyEmailReq } from '@passlock/shared/dist/rpc/user.js'
|
|
7
|
+
import type { Principal } from '@passlock/shared/dist/schema/principal.js'
|
|
9
8
|
import { Context, Effect as E, Layer, Option as O, flow, identity, pipe } from 'effect'
|
|
10
9
|
import { AuthenticationService, type AuthenticationErrors } from '../authentication/authenticate.js'
|
|
11
10
|
import { StorageService } from '../storage/storage.js'
|
|
@@ -38,7 +37,7 @@ export const EmailService = Context.GenericTag<EmailService>('@services/EmailSer
|
|
|
38
37
|
|
|
39
38
|
/* Utils */
|
|
40
39
|
|
|
41
|
-
export type Dependencies = StorageService | AuthenticationService |
|
|
40
|
+
export type Dependencies = StorageService | AuthenticationService | UserClient
|
|
42
41
|
|
|
43
42
|
/**
|
|
44
43
|
* Check for existing token in sessionStorage,
|
|
@@ -101,7 +100,7 @@ export const verifyEmail = (
|
|
|
101
100
|
const { token } = yield* _(getToken())
|
|
102
101
|
|
|
103
102
|
yield* _(E.logDebug('Making request'))
|
|
104
|
-
const client = yield* _(
|
|
103
|
+
const client = yield* _(UserClient)
|
|
105
104
|
const { principal } = yield* _(
|
|
106
105
|
client.verifyEmail(new VerifyEmailReq({ token, code: request.code })),
|
|
107
106
|
)
|
|
@@ -128,7 +127,7 @@ export const EmailServiceLive = Layer.effect(
|
|
|
128
127
|
EmailService,
|
|
129
128
|
E.gen(function* (_) {
|
|
130
129
|
const context = yield* _(
|
|
131
|
-
E.context<
|
|
130
|
+
E.context<UserClient | AuthenticationService | StorageService | URLQueryString>(),
|
|
132
131
|
)
|
|
133
132
|
return EmailService.of({
|
|
134
133
|
verifyEmailCode: flow(verifyEmail, E.provide(context)),
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
|
|
11
11
|
import { ErrorCode } from '@passlock/shared/dist/error/error.js'
|
|
12
12
|
import { RpcConfig } from '@passlock/shared/dist/rpc/config.js'
|
|
13
|
-
import type { Principal } from '@passlock/shared/dist/schema/
|
|
13
|
+
import type { Principal } from '@passlock/shared/dist/schema/principal.js'
|
|
14
14
|
import { Effect as E, Layer as L, Layer, Option, Runtime, Scope, pipe } from 'effect'
|
|
15
15
|
import { AuthenticationService, type AuthenticationRequest } from './authentication/authenticate.js'
|
|
16
16
|
import { Capabilities } from './capabilities/capabilities.js'
|
|
@@ -25,7 +25,10 @@ import { UserService, type Email, type ResendEmail } from './user/user.js'
|
|
|
25
25
|
/* Exports */
|
|
26
26
|
|
|
27
27
|
export type Options = { signal?: AbortSignal }
|
|
28
|
-
export type {
|
|
28
|
+
export type { VerifyEmail } from '@passlock/shared/dist/schema/email.js'
|
|
29
|
+
export type { UserVerification } from '@passlock/shared/dist/schema/passkey.js'
|
|
30
|
+
export type { Principal } from '@passlock/shared/dist/schema/principal.js'
|
|
31
|
+
|
|
29
32
|
export type { AuthenticationRequest } from './authentication/authenticate.js'
|
|
30
33
|
export type { VerifyRequest } from './email/email.js'
|
|
31
34
|
export type { RegistrationRequest } from './registration/register.js'
|
|
@@ -79,6 +79,7 @@ describe('log', () => {
|
|
|
79
79
|
const withLogLevel = logStatement.pipe(Logger.withMinimumLogLevel(LogLevel.Warning))
|
|
80
80
|
|
|
81
81
|
const effect = E.provide(withLogLevel, eventLoggerLive)
|
|
82
|
+
|
|
82
83
|
E.runSync(effect)
|
|
83
84
|
|
|
84
85
|
const expectedEvent = new CustomEvent('PasslogDebugMessage', {
|
|
@@ -21,15 +21,21 @@ export const logRaw = <T>(message: T) => {
|
|
|
21
21
|
|
|
22
22
|
export const DebugMessage = 'PasslogDebugMessage'
|
|
23
23
|
|
|
24
|
+
const dispatch = (message: string) => {
|
|
25
|
+
try {
|
|
26
|
+
const evt = new CustomEvent(DebugMessage, { detail: message })
|
|
27
|
+
globalThis.dispatchEvent(evt)
|
|
28
|
+
} catch (e) {
|
|
29
|
+
globalThis.console.log('Unable to fire custom event')
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
export const eventLoggerLive = Logger.add(
|
|
25
|
-
Logger.make(
|
|
26
|
-
if (typeof
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}),
|
|
34
|
+
Logger.make(({ logLevel, message }) => {
|
|
35
|
+
if (typeof message === 'string' && logLevel !== LogLevel.Debug) {
|
|
36
|
+
dispatch(message)
|
|
37
|
+
} else if (Array.isArray(message) && logLevel !== LogLevel.Debug) {
|
|
38
|
+
message.forEach(dispatch)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
35
41
|
)
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { PreConnectRes } from '@passlock/shared/dist/rpc/connection.js'
|
|
2
1
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
OptionsReq,
|
|
3
|
+
OptionsRes,
|
|
4
|
+
RegistrationClient,
|
|
5
|
+
VerificationReq,
|
|
6
|
+
VerificationRes,
|
|
7
7
|
} from '@passlock/shared/dist/rpc/registration.js'
|
|
8
|
-
import {
|
|
9
|
-
import type { RegistrationCredential } from '@passlock/shared/dist/schema/schema.js'
|
|
8
|
+
import type { RegistrationCredential } from '@passlock/shared/dist/schema/passkey.js'
|
|
10
9
|
import { Effect as E, Layer as L } from 'effect'
|
|
11
10
|
import * as Fixtures from '../test/fixtures.js'
|
|
12
11
|
import { UserService } from '../user/user.js'
|
|
@@ -75,19 +74,11 @@ export const userServiceTest = L.succeed(
|
|
|
75
74
|
)
|
|
76
75
|
|
|
77
76
|
export const rpcClientTest = L.succeed(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
preConnect: () => E.succeed(new PreConnectRes({ warmed: true })),
|
|
81
|
-
isExistingUser: () => E.fail(Fixtures.notImplemented),
|
|
82
|
-
verifyEmail: () => E.fail(Fixtures.notImplemented),
|
|
77
|
+
RegistrationClient,
|
|
78
|
+
RegistrationClient.of({
|
|
83
79
|
getRegistrationOptions: () => E.succeed(rpcOptionsRes),
|
|
84
80
|
verifyRegistrationCredential: () => E.succeed(rpcVerificationRes),
|
|
85
|
-
|
|
86
|
-
verifyAuthenticationCredential: () => E.fail(Fixtures.notImplemented),
|
|
87
|
-
registerOidc: () => E.fail(Fixtures.notImplemented),
|
|
88
|
-
authenticateOidc: () => E.fail(Fixtures.notImplemented),
|
|
89
|
-
resendVerificationEmail: () => E.fail(Fixtures.notImplemented),
|
|
90
|
-
}),
|
|
81
|
+
})
|
|
91
82
|
)
|
|
92
83
|
|
|
93
84
|
export const principal = Fixtures.principal
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Duplicate, InternalBrowserError } from '@passlock/shared/dist/error/error.js'
|
|
2
|
-
import {
|
|
2
|
+
import { RegistrationClient } from '@passlock/shared/dist/rpc/registration.js'
|
|
3
3
|
import { Effect as E, Layer as L, Layer, LogLevel, Logger, pipe } from 'effect'
|
|
4
4
|
import { describe, expect, test, vi } from 'vitest'
|
|
5
5
|
import { mock } from 'vitest-mock-extended'
|
|
@@ -33,14 +33,14 @@ describe('register should', () => {
|
|
|
33
33
|
const service = yield* _(RegistrationService)
|
|
34
34
|
yield* _(service.registerPasskey(Fixture.registrationRequest))
|
|
35
35
|
|
|
36
|
-
const rpcClient = yield* _(
|
|
36
|
+
const rpcClient = yield* _(RegistrationClient)
|
|
37
37
|
expect(rpcClient.getRegistrationOptions).toHaveBeenCalledWith(Fixture.rpcOptionsReq)
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
const rpcClientTest = L.effect(
|
|
41
|
-
|
|
41
|
+
RegistrationClient,
|
|
42
42
|
E.sync(() => {
|
|
43
|
-
const rpcMock = mock<
|
|
43
|
+
const rpcMock = mock<RegistrationClient['Type']>()
|
|
44
44
|
|
|
45
45
|
rpcMock.getRegistrationOptions.mockReturnValue(E.succeed(Fixture.rpcOptionsRes))
|
|
46
46
|
rpcMock.verifyRegistrationCredential.mockReturnValue(E.succeed(Fixture.rpcVerificationRes))
|
|
@@ -69,14 +69,14 @@ describe('register should', () => {
|
|
|
69
69
|
const service = yield* _(RegistrationService)
|
|
70
70
|
yield* _(service.registerPasskey(Fixture.registrationRequest))
|
|
71
71
|
|
|
72
|
-
const rpcClient = yield* _(
|
|
72
|
+
const rpcClient = yield* _(RegistrationClient)
|
|
73
73
|
expect(rpcClient.verifyRegistrationCredential).toHaveBeenCalledWith(Fixture.rpcVerificationReq)
|
|
74
74
|
})
|
|
75
75
|
|
|
76
76
|
const rpcClientTest = L.effect(
|
|
77
|
-
|
|
77
|
+
RegistrationClient,
|
|
78
78
|
E.sync(() => {
|
|
79
|
-
const rpcMock = mock<
|
|
79
|
+
const rpcMock = mock<RegistrationClient['Type']>()
|
|
80
80
|
|
|
81
81
|
rpcMock.getRegistrationOptions.mockReturnValue(E.succeed(Fixture.rpcOptionsRes))
|
|
82
82
|
rpcMock.verifyRegistrationCredential.mockReturnValue(E.succeed(Fixture.rpcVerificationRes))
|
|
@@ -110,9 +110,9 @@ describe('register should', () => {
|
|
|
110
110
|
})
|
|
111
111
|
|
|
112
112
|
const rpcClientTest = L.effect(
|
|
113
|
-
|
|
113
|
+
RegistrationClient,
|
|
114
114
|
E.sync(() => {
|
|
115
|
-
const rpcMock = mock<
|
|
115
|
+
const rpcMock = mock<RegistrationClient['Type']>()
|
|
116
116
|
|
|
117
117
|
rpcMock.getRegistrationOptions.mockReturnValue(E.fail(new Duplicate({ message: 'User already exists' })))
|
|
118
118
|
|
|
@@ -2,20 +2,19 @@
|
|
|
2
2
|
* User & passkey registration effects
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
parseCreationOptionsFromJSON,
|
|
6
|
+
type CredentialCreationOptionsJSON,
|
|
7
7
|
} from '@github/webauthn-json/browser-ponyfill'
|
|
8
8
|
import type { NotSupported } from '@passlock/shared/dist/error/error.js'
|
|
9
9
|
import { Duplicate, InternalBrowserError } from '@passlock/shared/dist/error/error.js'
|
|
10
10
|
import type { OptionsErrors, VerificationErrors } from '@passlock/shared/dist/rpc/registration.js'
|
|
11
|
-
import { OptionsReq, VerificationReq } from '@passlock/shared/dist/rpc/registration.js'
|
|
12
|
-
import {
|
|
11
|
+
import { OptionsReq, RegistrationClient, VerificationReq } from '@passlock/shared/dist/rpc/registration.js'
|
|
12
|
+
import { VerifyEmail } from '@passlock/shared/dist/schema/email.js'
|
|
13
13
|
import type {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} from '@passlock/shared/dist/schema/schema.js'
|
|
14
|
+
RegistrationCredential,
|
|
15
|
+
UserVerification,
|
|
16
|
+
} from '@passlock/shared/dist/schema/passkey.js'
|
|
17
|
+
import { Principal } from '@passlock/shared/dist/schema/principal.js'
|
|
19
18
|
import { Context, Effect as E, Layer, flow, pipe } from 'effect'
|
|
20
19
|
import { Capabilities } from '../capabilities/capabilities.js'
|
|
21
20
|
import { StorageService } from '../storage/storage.js'
|
|
@@ -59,7 +58,7 @@ const fetchOptions = (request: OptionsReq) => {
|
|
|
59
58
|
return E.gen(function* (_) {
|
|
60
59
|
yield* _(E.logDebug('Making request'))
|
|
61
60
|
|
|
62
|
-
const rpcClient = yield* _(
|
|
61
|
+
const rpcClient = yield* _(RegistrationClient)
|
|
63
62
|
const { publicKey, session } = yield* _(rpcClient.getRegistrationOptions(request))
|
|
64
63
|
|
|
65
64
|
yield* _(E.logDebug('Converting Passlock options to CredentialCreationOptions'))
|
|
@@ -86,7 +85,7 @@ const verifyCredential = (request: VerificationReq) => {
|
|
|
86
85
|
return E.gen(function* (_) {
|
|
87
86
|
yield* _(E.logDebug('Making request'))
|
|
88
87
|
|
|
89
|
-
const rpcClient = yield* _(
|
|
88
|
+
const rpcClient = yield* _(RegistrationClient)
|
|
90
89
|
const { principal } = yield* _(rpcClient.verifyRegistrationCredential(request))
|
|
91
90
|
|
|
92
91
|
return principal
|
|
@@ -95,7 +94,7 @@ const verifyCredential = (request: VerificationReq) => {
|
|
|
95
94
|
|
|
96
95
|
/* Effects */
|
|
97
96
|
|
|
98
|
-
type Dependencies = Capabilities | CreateCredential | StorageService | UserService |
|
|
97
|
+
type Dependencies = Capabilities | CreateCredential | StorageService | UserService | RegistrationClient
|
|
99
98
|
|
|
100
99
|
export const registerPasskey = (
|
|
101
100
|
request: RegistrationRequest,
|
|
@@ -146,7 +145,7 @@ export const RegistrationServiceLive = Layer.effect(
|
|
|
146
145
|
RegistrationService,
|
|
147
146
|
E.gen(function* (_) {
|
|
148
147
|
const context = yield* _(
|
|
149
|
-
E.context<CreateCredential |
|
|
148
|
+
E.context<CreateCredential | RegistrationClient | Capabilities | StorageService | UserService>(),
|
|
150
149
|
)
|
|
151
150
|
|
|
152
151
|
return RegistrationService.of({
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { PreConnectRes } from '@passlock/shared/dist/rpc/connection.js'
|
|
2
|
-
import { RpcClient } from '@passlock/shared/dist/rpc/rpc.js'
|
|
3
1
|
import * as Shared from '@passlock/shared/dist/rpc/social.js'
|
|
4
|
-
import {
|
|
2
|
+
import { SocialClient } from '@passlock/shared/dist/rpc/social.js'
|
|
3
|
+
import { Effect as E, Layer as L } from 'effect'
|
|
5
4
|
import * as Fixtures from '../test/fixtures.js'
|
|
6
5
|
import type { AuthenticateOidcReq, RegisterOidcReq } from './social.js'
|
|
7
6
|
|
|
@@ -27,8 +26,8 @@ export const authOidcReq: AuthenticateOidcReq = {
|
|
|
27
26
|
|
|
28
27
|
export const rpcRegisterReq = new Shared.RegisterOidcReq({
|
|
29
28
|
...registerOidcReq,
|
|
30
|
-
givenName:
|
|
31
|
-
familyName:
|
|
29
|
+
...(registerOidcReq.givenName ? { givenName: registerOidcReq.givenName } : {}),
|
|
30
|
+
...(registerOidcReq.familyName ? { familyName: registerOidcReq.familyName } : {})
|
|
32
31
|
})
|
|
33
32
|
|
|
34
33
|
export const rpcRegisterRes = new Shared.PrincipalRes({ principal: Fixtures.principal })
|
|
@@ -38,19 +37,11 @@ export const rpcAuthenticateReq = new Shared.AuthOidcReq({ ...authOidcReq })
|
|
|
38
37
|
export const rpcAuthenticateRes = new Shared.PrincipalRes({ principal: Fixtures.principal })
|
|
39
38
|
|
|
40
39
|
export const rpcClientTest = L.succeed(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
preConnect: () => E.succeed(new PreConnectRes({ warmed: true })),
|
|
44
|
-
isExistingUser: () => E.fail(Fixtures.notImplemented),
|
|
45
|
-
verifyEmail: () => E.fail(Fixtures.notImplemented),
|
|
46
|
-
getRegistrationOptions: () => E.fail(Fixtures.notImplemented),
|
|
47
|
-
verifyRegistrationCredential: () => E.fail(Fixtures.notImplemented),
|
|
48
|
-
getAuthenticationOptions: () => E.fail(Fixtures.notImplemented),
|
|
49
|
-
verifyAuthenticationCredential: () => E.fail(Fixtures.notImplemented),
|
|
40
|
+
SocialClient,
|
|
41
|
+
SocialClient.of({
|
|
50
42
|
registerOidc: () => E.fail(Fixtures.notImplemented),
|
|
51
43
|
authenticateOidc: () => E.fail(Fixtures.notImplemented),
|
|
52
|
-
|
|
53
|
-
}),
|
|
44
|
+
})
|
|
54
45
|
)
|
|
55
46
|
|
|
56
47
|
export const principal = Fixtures.principal
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Duplicate, NotFound } from '@passlock/shared/dist/error/error.js'
|
|
2
|
-
import {
|
|
2
|
+
import { SocialClient } from '@passlock/shared/dist/rpc/social.js'
|
|
3
3
|
import { Effect as E, Layer as L, Layer, LogLevel, Logger, pipe } from 'effect'
|
|
4
4
|
import { describe, expect, test } from 'vitest'
|
|
5
5
|
import { mock } from 'vitest-mock-extended'
|
|
@@ -15,9 +15,9 @@ describe('registerOidc should', () => {
|
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
const rpcClientTest = L.effect(
|
|
18
|
-
|
|
18
|
+
SocialClient,
|
|
19
19
|
E.sync(() => {
|
|
20
|
-
const rpcMock = mock<
|
|
20
|
+
const rpcMock = mock<SocialClient['Type']>()
|
|
21
21
|
|
|
22
22
|
rpcMock.registerOidc.mockReturnValue(E.succeed(Fixture.rpcRegisterRes))
|
|
23
23
|
|
|
@@ -41,14 +41,14 @@ describe('registerOidc should', () => {
|
|
|
41
41
|
const service = yield* _(SocialService)
|
|
42
42
|
yield* _(service.registerOidc(Fixture.registerOidcReq))
|
|
43
43
|
|
|
44
|
-
const rpcClient = yield* _(
|
|
44
|
+
const rpcClient = yield* _(SocialClient)
|
|
45
45
|
expect(rpcClient.registerOidc).toHaveBeenCalledWith(Fixture.rpcRegisterReq)
|
|
46
46
|
})
|
|
47
47
|
|
|
48
48
|
const rpcClientTest = L.effect(
|
|
49
|
-
|
|
49
|
+
SocialClient,
|
|
50
50
|
E.sync(() => {
|
|
51
|
-
const rpcMock = mock<
|
|
51
|
+
const rpcMock = mock<SocialClient['Type']>()
|
|
52
52
|
|
|
53
53
|
rpcMock.registerOidc.mockReturnValue(E.succeed(Fixture.rpcRegisterRes))
|
|
54
54
|
|
|
@@ -77,9 +77,9 @@ describe('registerOidc should', () => {
|
|
|
77
77
|
})
|
|
78
78
|
|
|
79
79
|
const rpcClientTest = L.effect(
|
|
80
|
-
|
|
80
|
+
SocialClient,
|
|
81
81
|
E.sync(() => {
|
|
82
|
-
const rpcMock = mock<
|
|
82
|
+
const rpcMock = mock<SocialClient['Type']>()
|
|
83
83
|
|
|
84
84
|
rpcMock.registerOidc.mockReturnValue(E.fail(new Duplicate({ message: "Duplicate user" })))
|
|
85
85
|
|
|
@@ -108,9 +108,9 @@ describe('authenticateIodc should', () => {
|
|
|
108
108
|
})
|
|
109
109
|
|
|
110
110
|
const rpcClientTest = L.effect(
|
|
111
|
-
|
|
111
|
+
SocialClient,
|
|
112
112
|
E.sync(() => {
|
|
113
|
-
const rpcMock = mock<
|
|
113
|
+
const rpcMock = mock<SocialClient['Type']>()
|
|
114
114
|
|
|
115
115
|
rpcMock.authenticateOidc.mockReturnValue(E.succeed(Fixture.rpcRegisterRes))
|
|
116
116
|
|
|
@@ -134,14 +134,14 @@ describe('authenticateIodc should', () => {
|
|
|
134
134
|
const service = yield* _(SocialService)
|
|
135
135
|
yield* _(service.authenticateOidc(Fixture.authOidcReq))
|
|
136
136
|
|
|
137
|
-
const rpcClient = yield* _(
|
|
137
|
+
const rpcClient = yield* _(SocialClient)
|
|
138
138
|
expect(rpcClient.authenticateOidc).toHaveBeenCalledWith(Fixture.rpcAuthenticateReq)
|
|
139
139
|
})
|
|
140
140
|
|
|
141
141
|
const rpcClientTest = L.effect(
|
|
142
|
-
|
|
142
|
+
SocialClient,
|
|
143
143
|
E.sync(() => {
|
|
144
|
-
const rpcMock = mock<
|
|
144
|
+
const rpcMock = mock<SocialClient['Type']>()
|
|
145
145
|
|
|
146
146
|
rpcMock.authenticateOidc.mockReturnValue(E.succeed(Fixture.rpcAuthenticateRes))
|
|
147
147
|
|
|
@@ -170,9 +170,9 @@ describe('authenticateIodc should', () => {
|
|
|
170
170
|
})
|
|
171
171
|
|
|
172
172
|
const rpcClientTest = L.effect(
|
|
173
|
-
|
|
173
|
+
SocialClient,
|
|
174
174
|
E.sync(() => {
|
|
175
|
-
const rpcMock = mock<
|
|
175
|
+
const rpcMock = mock<SocialClient['Type']>()
|
|
176
176
|
|
|
177
177
|
rpcMock.authenticateOidc.mockReturnValue(E.fail(new NotFound({ message: "User not found" })))
|
|
178
178
|
|
package/src/social/social.ts
CHANGED
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
type BadRequest,
|
|
6
6
|
type NotSupported
|
|
7
7
|
} from '@passlock/shared/dist/error/error.js'
|
|
8
|
-
import { RpcClient } from '@passlock/shared/dist/rpc/rpc.js'
|
|
9
8
|
import * as Shared from '@passlock/shared/dist/rpc/social.js'
|
|
9
|
+
import { SocialClient } from '@passlock/shared/dist/rpc/social.js'
|
|
10
10
|
import type {
|
|
11
11
|
Principal
|
|
12
|
-
} from '@passlock/shared/dist/schema/
|
|
13
|
-
import { Context, Effect as E, Layer,
|
|
12
|
+
} from '@passlock/shared/dist/schema/principal.js'
|
|
13
|
+
import { Context, Effect as E, Layer, flow } from 'effect'
|
|
14
14
|
|
|
15
15
|
/* Requests */
|
|
16
16
|
|
|
@@ -49,7 +49,7 @@ export const SocialService = Context.GenericTag<SocialService>(
|
|
|
49
49
|
|
|
50
50
|
/* Effects */
|
|
51
51
|
|
|
52
|
-
type Dependencies =
|
|
52
|
+
type Dependencies = SocialClient
|
|
53
53
|
|
|
54
54
|
export const registerOidc = (
|
|
55
55
|
request: RegisterOidcReq,
|
|
@@ -57,12 +57,12 @@ export const registerOidc = (
|
|
|
57
57
|
return E.gen(function* (_) {
|
|
58
58
|
yield* _(E.logInfo('Registering social account'))
|
|
59
59
|
|
|
60
|
-
const rpcClient = yield* _(
|
|
60
|
+
const rpcClient = yield* _(SocialClient)
|
|
61
61
|
|
|
62
62
|
const rpcRequest = new Shared.RegisterOidcReq({
|
|
63
63
|
...request,
|
|
64
|
-
givenName:
|
|
65
|
-
familyName:
|
|
64
|
+
...(request.givenName ? { givenName: request.givenName } : {}),
|
|
65
|
+
...(request.familyName ? { familyName: request.familyName } : {})
|
|
66
66
|
})
|
|
67
67
|
|
|
68
68
|
const { principal } = yield* _(
|
|
@@ -79,7 +79,7 @@ export const authenticateOidc = (
|
|
|
79
79
|
return E.gen(function* (_) {
|
|
80
80
|
yield* _(E.logInfo('Authenticating with social account'))
|
|
81
81
|
|
|
82
|
-
const rpcClient = yield* _(
|
|
82
|
+
const rpcClient = yield* _(SocialClient)
|
|
83
83
|
const rpcRequest = new Shared.AuthOidcReq(request)
|
|
84
84
|
|
|
85
85
|
const { principal } = yield* _(
|
|
@@ -96,7 +96,7 @@ export const authenticateOidc = (
|
|
|
96
96
|
export const SocialServiceLive = Layer.effect(
|
|
97
97
|
SocialService,
|
|
98
98
|
E.gen(function* (_) {
|
|
99
|
-
const context = yield* _(E.context<
|
|
99
|
+
const context = yield* _(E.context<SocialClient>())
|
|
100
100
|
|
|
101
101
|
return SocialService.of({
|
|
102
102
|
registerOidc: flow(registerOidc, E.provide(context)),
|
package/src/storage/storage.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Wrapper around local storage that allows us to store
|
|
3
3
|
* authentication tokens in local storage for a short period.
|
|
4
4
|
*/
|
|
5
|
-
import type { Principal } from '@passlock/shared/dist/schema/
|
|
5
|
+
import type { Principal } from '@passlock/shared/dist/schema/principal.js'
|
|
6
6
|
import { Context, Effect as E, Layer, Option as O, flow, pipe } from 'effect'
|
|
7
7
|
import type { NoSuchElementException } from 'effect/Cause'
|
|
8
8
|
|
package/src/test/fixtures.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { BadRequest } from '@passlock/shared/dist/error/error.js'
|
|
2
|
-
import {
|
|
3
|
-
import type { Principal } from '@passlock/shared/dist/schema/schema.js'
|
|
2
|
+
import type { Principal } from '@passlock/shared/dist/schema/principal.js'
|
|
4
3
|
import { Effect as E, Layer as L } from 'effect'
|
|
5
4
|
import { Capabilities } from '../capabilities/capabilities.js'
|
|
6
5
|
import { StorageService, type StoredToken } from '../storage/storage.js'
|
|
@@ -51,5 +50,4 @@ export const storageServiceTest = L.succeed(
|
|
|
51
50
|
}),
|
|
52
51
|
)
|
|
53
52
|
|
|
54
|
-
export const preConnectRes = new PreConnectRes({ warmed: true })
|
|
55
53
|
export const notImplemented = new BadRequest({ message: 'Not implemented' })
|
package/src/user/user.fixture.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { IsExistingUserReq, IsExistingUserRes, ResendEmailReq, ResendEmailRes, VerifyEmailRes } from '@passlock/shared/dist/rpc/user.js'
|
|
1
|
+
import { IsExistingUserReq, IsExistingUserRes, ResendEmailReq, ResendEmailRes, UserClient, VerifyEmailRes } from '@passlock/shared/dist/rpc/user.js'
|
|
3
2
|
import { Effect as E, Layer as L } from 'effect'
|
|
4
3
|
import * as Fixtures from '../test/fixtures.js'
|
|
5
4
|
import type { ResendEmail } from './user.js'
|
|
@@ -13,17 +12,10 @@ export const rpcResendEmailReq = new ResendEmailReq({ userId: '123', verifyEmail
|
|
|
13
12
|
export const rpcResendEmailRes = new ResendEmailRes({ })
|
|
14
13
|
|
|
15
14
|
export const rpcClientTest = L.succeed(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
preConnect: () => E.succeed({ warmed: true }),
|
|
15
|
+
UserClient,
|
|
16
|
+
UserClient.of({
|
|
19
17
|
isExistingUser: () => E.succeed({ existingUser: true }),
|
|
20
18
|
verifyEmail: () => E.succeed(verifyEmailRes),
|
|
21
|
-
getRegistrationOptions: () => E.fail(Fixtures.notImplemented),
|
|
22
|
-
verifyRegistrationCredential: () => E.fail(Fixtures.notImplemented),
|
|
23
|
-
getAuthenticationOptions: () => E.fail(Fixtures.notImplemented),
|
|
24
|
-
verifyAuthenticationCredential: () => E.fail(Fixtures.notImplemented),
|
|
25
|
-
registerOidc: () => E.fail(Fixtures.notImplemented),
|
|
26
|
-
authenticateOidc: () => E.fail(Fixtures.notImplemented),
|
|
27
19
|
resendVerificationEmail: () => E.fail(Fixtures.notImplemented),
|
|
28
20
|
}),
|
|
29
21
|
)
|
package/src/user/user.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UserClient } from '@passlock/shared/dist/rpc/user.js'
|
|
2
2
|
import { Effect as E, Layer as L, Layer, LogLevel, Logger, pipe } from 'effect'
|
|
3
3
|
import { describe, expect, test } from 'vitest'
|
|
4
4
|
import { mock } from 'vitest-mock-extended'
|
|
@@ -27,14 +27,14 @@ describe('isExistingUser should', () => {
|
|
|
27
27
|
const result = yield* _(service.isExistingUser({ email: Fixture.email }))
|
|
28
28
|
|
|
29
29
|
expect(result).toBe(false)
|
|
30
|
-
const rpcClient = yield* _(
|
|
30
|
+
const rpcClient = yield* _(UserClient)
|
|
31
31
|
expect(rpcClient.isExistingUser).toBeCalledWith(Fixture.isRegisteredReq)
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
const rpcClientTest = Layer.effect(
|
|
35
|
-
|
|
35
|
+
UserClient,
|
|
36
36
|
E.sync(() => {
|
|
37
|
-
const rpcMock = mock<
|
|
37
|
+
const rpcMock = mock<UserClient['Type']>()
|
|
38
38
|
|
|
39
39
|
rpcMock.isExistingUser.mockReturnValue(E.succeed(Fixture.isRegisteredRes))
|
|
40
40
|
|
|
@@ -57,14 +57,14 @@ describe('resendVerificationEmail should', () => {
|
|
|
57
57
|
const service = yield* _(UserService)
|
|
58
58
|
yield* _(service.resendVerificationEmail(Fixture.resendEmailReq))
|
|
59
59
|
|
|
60
|
-
const rpcClient = yield* _(
|
|
60
|
+
const rpcClient = yield* _(UserClient)
|
|
61
61
|
expect(rpcClient.resendVerificationEmail).toBeCalledWith(Fixture.rpcResendEmailReq)
|
|
62
62
|
})
|
|
63
63
|
|
|
64
64
|
const rpcClientTest = Layer.effect(
|
|
65
|
-
|
|
65
|
+
UserClient,
|
|
66
66
|
E.sync(() => {
|
|
67
|
-
const rpcMock = mock<
|
|
67
|
+
const rpcMock = mock<UserClient['Type']>()
|
|
68
68
|
|
|
69
69
|
rpcMock.resendVerificationEmail.mockReturnValue(E.succeed(Fixture.rpcResendEmailRes))
|
|
70
70
|
|
package/src/user/user.ts
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Check for an existing user
|
|
3
3
|
*/
|
|
4
4
|
import type { BadRequest, Disabled, NotFound } from '@passlock/shared/dist/error/error.js'
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import type { VerifyEmail } from '@passlock/shared/dist/schema/schema.js'
|
|
5
|
+
import { IsExistingUserReq, ResendEmailReq, UserClient } from '@passlock/shared/dist/rpc/user.js'
|
|
6
|
+
import type { VerifyEmail } from '@passlock/shared/dist/schema/email.js'
|
|
8
7
|
import { Context, Effect as E, Layer, flow } from 'effect'
|
|
9
8
|
|
|
10
9
|
/* Requests */
|
|
@@ -27,12 +26,12 @@ export const UserService = Context.GenericTag<UserService>('@services/UserServic
|
|
|
27
26
|
|
|
28
27
|
/* Effects */
|
|
29
28
|
|
|
30
|
-
type Dependencies =
|
|
29
|
+
type Dependencies = UserClient
|
|
31
30
|
|
|
32
31
|
export const isExistingUser = (request: Email): E.Effect<boolean, BadRequest, Dependencies> => {
|
|
33
32
|
return E.gen(function* (_) {
|
|
34
33
|
yield* _(E.logInfo('Checking registration status'))
|
|
35
|
-
const rpcClient = yield* _(
|
|
34
|
+
const rpcClient = yield* _(UserClient)
|
|
36
35
|
|
|
37
36
|
yield* _(E.logDebug('Making RPC request'))
|
|
38
37
|
const { existingUser } = yield* _(rpcClient.isExistingUser(new IsExistingUserReq(request)))
|
|
@@ -44,7 +43,7 @@ export const isExistingUser = (request: Email): E.Effect<boolean, BadRequest, De
|
|
|
44
43
|
export const resendVerificationEmail = (request: ResendEmail): E.Effect<void, ResendEmailErrors, Dependencies> => {
|
|
45
44
|
return E.gen(function* (_) {
|
|
46
45
|
yield* _(E.logInfo('Resending verification email'))
|
|
47
|
-
const rpcClient = yield* _(
|
|
46
|
+
const rpcClient = yield* _(UserClient)
|
|
48
47
|
|
|
49
48
|
yield* _(E.logDebug('Making RPC request'))
|
|
50
49
|
const { userId, ...verifyEmail } = request
|
|
@@ -58,7 +57,7 @@ export const resendVerificationEmail = (request: ResendEmail): E.Effect<void, Re
|
|
|
58
57
|
export const UserServiceLive = Layer.effect(
|
|
59
58
|
UserService,
|
|
60
59
|
E.gen(function* (_) {
|
|
61
|
-
const context = yield* _(E.context<
|
|
60
|
+
const context = yield* _(E.context<UserClient>())
|
|
62
61
|
return UserService.of({
|
|
63
62
|
isExistingUser: flow(isExistingUser, E.provide(context)),
|
|
64
63
|
resendVerificationEmail: flow(resendVerificationEmail, E.provide(context))
|