@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.
- package/dist/authentication/authenticate.d.ts +15 -15
- package/dist/authentication/authenticate.fixture.d.ts +20 -6
- package/dist/authentication/authenticate.fixture.js +7 -5
- package/dist/authentication/authenticate.fixture.js.map +1 -1
- package/dist/authentication/authenticate.js +19 -8
- package/dist/authentication/authenticate.js.map +1 -1
- package/dist/capabilities/capabilities.d.ts +8 -4
- package/dist/capabilities/capabilities.js +10 -1
- package/dist/capabilities/capabilities.js.map +1 -1
- package/dist/connection/connection.d.ts +11 -7
- package/dist/connection/connection.fixture.d.ts +2 -2
- package/dist/connection/connection.fixture.js +2 -1
- package/dist/connection/connection.fixture.js.map +1 -1
- package/dist/connection/connection.js +12 -3
- package/dist/connection/connection.js.map +1 -1
- package/dist/effect.d.ts +22 -45
- package/dist/effect.js +55 -51
- package/dist/effect.js.map +1 -1
- package/dist/email/email.d.ts +38 -11
- package/dist/email/email.fixture.d.ts +19 -5
- package/dist/email/email.fixture.js +4 -3
- package/dist/email/email.fixture.js.map +1 -1
- package/dist/email/email.js +43 -7
- package/dist/email/email.js.map +1 -1
- package/dist/event/event.d.ts +3 -1
- package/dist/event/event.js +3 -0
- package/dist/event/event.js.map +1 -1
- package/dist/index.d.ts +105 -27
- package/dist/index.js +101 -50
- package/dist/index.js.map +1 -1
- package/dist/logging/eventLogger.d.ts +13 -1
- package/dist/logging/eventLogger.js +13 -0
- package/dist/logging/eventLogger.js.map +1 -1
- package/dist/registration/register.d.ts +18 -21
- package/dist/registration/register.fixture.d.ts +19 -5
- package/dist/registration/register.fixture.js +14 -7
- package/dist/registration/register.fixture.js.map +1 -1
- package/dist/registration/register.js +18 -9
- package/dist/registration/register.js.map +1 -1
- package/dist/rpc/authentication.d.ts +0 -1
- package/dist/rpc/authentication.js +1 -0
- package/dist/rpc/authentication.js.map +1 -1
- package/dist/rpc/client.d.ts +4 -1
- package/dist/rpc/client.js +12 -2
- package/dist/rpc/client.js.map +1 -1
- package/dist/rpc/config.d.ts +0 -1
- package/dist/rpc/connection.d.ts +0 -1
- package/dist/rpc/connection.js +1 -0
- package/dist/rpc/connection.js.map +1 -1
- package/dist/rpc/registration.d.ts +0 -1
- package/dist/rpc/registration.js +1 -0
- package/dist/rpc/registration.js.map +1 -1
- package/dist/rpc/social.d.ts +0 -1
- package/dist/rpc/social.js +1 -0
- package/dist/rpc/social.js.map +1 -1
- package/dist/rpc/user.d.ts +0 -1
- package/dist/rpc/user.js +1 -0
- package/dist/rpc/user.js.map +1 -1
- package/dist/social/social.d.ts +16 -23
- package/dist/social/social.fixture.d.ts +21 -9
- package/dist/social/social.fixture.js +8 -14
- package/dist/social/social.fixture.js.map +1 -1
- package/dist/social/social.js +14 -10
- package/dist/social/social.js.map +1 -1
- package/dist/storage/storage.d.ts +40 -12
- package/dist/storage/storage.fixture.d.ts +2 -2
- package/dist/storage/storage.fixture.js +2 -2
- package/dist/storage/storage.fixture.js.map +1 -1
- package/dist/storage/storage.js +48 -15
- package/dist/storage/storage.js.map +1 -1
- package/dist/test/fixtures.d.ts +1 -2
- package/dist/test/fixtures.js +20 -5
- package/dist/test/fixtures.js.map +1 -1
- package/dist/user/user.d.ts +8 -5
- package/dist/user/user.fixture.d.ts +2 -2
- package/dist/user/user.fixture.js +9 -5
- package/dist/user/user.fixture.js.map +1 -1
- package/dist/user/user.js +9 -3
- package/dist/user/user.js.map +1 -1
- package/dist/version.d.ts +1 -2
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +30 -26
- package/src/authentication/authenticate.fixture.ts +8 -7
- package/src/authentication/authenticate.test.ts +59 -17
- package/src/authentication/authenticate.ts +34 -32
- package/src/capabilities/capabilities.ts +9 -8
- package/src/connection/connection.fixture.ts +2 -1
- package/src/connection/connection.test.ts +3 -3
- package/src/connection/connection.ts +9 -8
- package/src/effect.ts +129 -128
- package/src/email/email.fixture.ts +4 -3
- package/src/email/email.test.ts +4 -4
- package/src/email/email.ts +24 -16
- package/src/index.ts +225 -169
- package/src/logging/eventLogger.test.ts +1 -1
- package/src/logging/eventLogger.ts +2 -2
- package/src/registration/register.fixture.ts +14 -8
- package/src/registration/register.test.ts +13 -9
- package/src/registration/register.ts +37 -34
- package/src/rpc/authentication.ts +31 -0
- package/src/rpc/client.ts +173 -0
- package/src/rpc/config.ts +18 -0
- package/src/rpc/connection.ts +24 -0
- package/src/rpc/registration.ts +31 -0
- package/src/rpc/social.ts +36 -0
- package/src/rpc/user.ts +42 -0
- package/src/social/social.fixture.ts +10 -18
- package/src/social/social.test.ts +13 -29
- package/src/social/social.ts +20 -47
- package/src/storage/storage.fixture.ts +3 -4
- package/src/storage/storage.test.ts +28 -19
- package/src/storage/storage.ts +36 -36
- package/src/test/fixtures.ts +21 -6
- package/src/user/user.fixture.ts +17 -7
- package/src/user/user.test.ts +2 -5
- package/src/user/user.ts +13 -9
- package/src/version.ts +1 -0
- package/dist/authentication/authenticate.d.ts.map +0 -1
- package/dist/authentication/authenticate.fixture.d.ts.map +0 -1
- package/dist/capabilities/capabilities.d.ts.map +0 -1
- package/dist/config.d.ts +0 -18
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -20
- package/dist/config.js.map +0 -1
- package/dist/connection/connection.d.ts.map +0 -1
- package/dist/connection/connection.fixture.d.ts.map +0 -1
- package/dist/effect.d.ts.map +0 -1
- package/dist/email/email.d.ts.map +0 -1
- package/dist/email/email.fixture.d.ts.map +0 -1
- package/dist/event/event.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/logging/eventLogger.d.ts.map +0 -1
- package/dist/registration/register.d.ts.map +0 -1
- package/dist/registration/register.fixture.d.ts.map +0 -1
- package/dist/rpc/authentication.d.ts.map +0 -1
- package/dist/rpc/client.d.ts.map +0 -1
- package/dist/rpc/config.d.ts.map +0 -1
- package/dist/rpc/connection.d.ts.map +0 -1
- package/dist/rpc/registration.d.ts.map +0 -1
- package/dist/rpc/social.d.ts.map +0 -1
- package/dist/rpc/user.d.ts.map +0 -1
- package/dist/social/social.d.ts.map +0 -1
- package/dist/social/social.fixture.d.ts.map +0 -1
- package/dist/storage/storage.d.ts.map +0 -1
- package/dist/storage/storage.fixture.d.ts.map +0 -1
- package/dist/test/fixtures.d.ts.map +0 -1
- package/dist/user/user.d.ts.map +0 -1
- package/dist/user/user.fixture.d.ts.map +0 -1
- package/dist/version.d.ts.map +0 -1
- package/src/config.ts +0 -42
package/dist/test/fixtures.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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"}
|
package/dist/user/user.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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({
|
|
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,
|
|
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
|
|
1
|
+
import { IsExistingUserReq, ResendEmailReq } from '@passlock/shared/dist/rpc/user.js';
|
|
2
2
|
import { Context, Effect as E, Layer, flow } from 'effect';
|
|
3
|
-
|
|
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
|
package/dist/user/user.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/user/user.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,
|
|
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
|
|
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
|
|
1
|
+
export const PASSLOCK_CLIENT_VERSION = '0.9.23';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,
|
|
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.
|
|
4
|
-
"description": "
|
|
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://
|
|
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.
|
|
47
|
-
"@passlock/shared": "0.9.
|
|
49
|
+
"effect": "3.6.3",
|
|
50
|
+
"@passlock/shared": "0.9.23"
|
|
48
51
|
},
|
|
49
52
|
"devDependencies": {
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
"eslint": "^8.
|
|
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
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
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.
|
|
66
|
-
"vite": "^5.
|
|
67
|
-
"vitest": "^2.0.
|
|
68
|
-
"vitest-mock-extended": "^
|
|
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": "
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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 {
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
227
|
+
const getCredential = vi.fn()
|
|
186
228
|
|
|
187
|
-
|
|
229
|
+
getCredential.mockReturnValue(E.succeed(Fixture.credential))
|
|
188
230
|
|
|
189
|
-
return
|
|
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
|
-
|
|
10
|
-
type
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import type {
|
|
15
|
-
|
|
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
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
104
|
+
|
|
105
|
+
const { options, session } = yield* _(fetchOptions(request))
|
|
106
106
|
|
|
107
107
|
yield* _(E.logInfo('Looking up credential'))
|
|
108
|
-
const
|
|
109
|
-
const credential = yield* _(
|
|
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* _(
|
|
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
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 {
|
|
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
|
|