@effect-auth/core 0.1.0-alpha.3 → 0.1.0-alpha.4
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/README.md +148 -13
- package/dist/ApiKey.d.ts +207 -0
- package/dist/ApiKey.d.ts.map +1 -0
- package/dist/ApiKey.js +275 -0
- package/dist/ApiKey.js.map +1 -0
- package/dist/AuditLog.d.ts +204 -1
- package/dist/AuditLog.d.ts.map +1 -1
- package/dist/AuditLog.js +170 -0
- package/dist/AuditLog.js.map +1 -1
- package/dist/AuthConfig.d.ts +0 -9
- package/dist/AuthConfig.d.ts.map +1 -1
- package/dist/AuthConfig.js +1 -14
- package/dist/AuthConfig.js.map +1 -1
- package/dist/AuthFlow.d.ts +220 -51
- package/dist/AuthFlow.d.ts.map +1 -1
- package/dist/AuthFlow.js +550 -22
- package/dist/AuthFlow.js.map +1 -1
- package/dist/AuthKernel.d.ts +1 -1
- package/dist/Challenge.d.ts +5 -1
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +58 -48
- package/dist/Challenge.js.map +1 -1
- package/dist/Client.d.ts +242 -1
- package/dist/Client.d.ts.map +1 -1
- package/dist/Client.js +489 -1
- package/dist/Client.js.map +1 -1
- package/dist/D1Kysely.d.ts +1 -1
- package/dist/D1Kysely.d.ts.map +1 -1
- package/dist/EffectQbSqliteStorage.d.ts +115 -3
- package/dist/EffectQbSqliteStorage.d.ts.map +1 -1
- package/dist/EffectQbSqliteStorage.js +314 -4
- package/dist/EffectQbSqliteStorage.js.map +1 -1
- package/dist/EmailOtp.d.ts +5 -2
- package/dist/EmailOtp.d.ts.map +1 -1
- package/dist/EmailOtp.js +11 -4
- package/dist/EmailOtp.js.map +1 -1
- package/dist/EmailVerification.d.ts +2 -2
- package/dist/EmailVerification.d.ts.map +1 -1
- package/dist/EmailVerification.js +2 -3
- package/dist/EmailVerification.js.map +1 -1
- package/dist/HttpApi/Api.d.ts +1161 -19
- package/dist/HttpApi/Api.d.ts.map +1 -1
- package/dist/HttpApi/Api.js +1433 -20
- package/dist/HttpApi/Api.js.map +1 -1
- package/dist/HttpApi/Endpoints.d.ts +611 -0
- package/dist/HttpApi/Endpoints.d.ts.map +1 -1
- package/dist/HttpApi/Endpoints.js +242 -1
- package/dist/HttpApi/Endpoints.js.map +1 -1
- package/dist/HttpApi/Schemas.d.ts +704 -0
- package/dist/HttpApi/Schemas.d.ts.map +1 -1
- package/dist/HttpApi/Schemas.js +435 -1
- package/dist/HttpApi/Schemas.js.map +1 -1
- package/dist/HttpApi/Security.d.ts +13 -1
- package/dist/HttpApi/Security.d.ts.map +1 -1
- package/dist/HttpApi/Security.js +107 -16
- package/dist/HttpApi/Security.js.map +1 -1
- package/dist/HttpApi/Transport.d.ts +36 -2
- package/dist/HttpApi/Transport.d.ts.map +1 -1
- package/dist/HttpApi/Transport.js +151 -9
- package/dist/HttpApi/Transport.js.map +1 -1
- package/dist/Jwt.d.ts +271 -0
- package/dist/Jwt.d.ts.map +1 -0
- package/dist/Jwt.js +512 -0
- package/dist/Jwt.js.map +1 -0
- package/dist/KyselyStorage.d.ts +134 -1
- package/dist/KyselyStorage.d.ts.map +1 -1
- package/dist/KyselyStorage.js +918 -4
- package/dist/KyselyStorage.js.map +1 -1
- package/dist/LoginApproval.d.ts +314 -0
- package/dist/LoginApproval.d.ts.map +1 -0
- package/dist/LoginApproval.js +551 -0
- package/dist/LoginApproval.js.map +1 -0
- package/dist/LoginNotification.d.ts +183 -0
- package/dist/LoginNotification.d.ts.map +1 -0
- package/dist/LoginNotification.js +329 -0
- package/dist/LoginNotification.js.map +1 -0
- package/dist/LoginRisk.d.ts +73 -0
- package/dist/LoginRisk.d.ts.map +1 -0
- package/dist/LoginRisk.js +57 -0
- package/dist/LoginRisk.js.map +1 -0
- package/dist/MagicLink.d.ts +85 -0
- package/dist/MagicLink.d.ts.map +1 -0
- package/dist/MagicLink.js +206 -0
- package/dist/MagicLink.js.map +1 -0
- package/dist/Mailer.d.ts +33 -2
- package/dist/Mailer.d.ts.map +1 -1
- package/dist/Mailer.js +107 -0
- package/dist/Mailer.js.map +1 -1
- package/dist/Passkey.d.ts +334 -0
- package/dist/Passkey.d.ts.map +1 -0
- package/dist/Passkey.js +422 -0
- package/dist/Passkey.js.map +1 -0
- package/dist/Password.d.ts +138 -8
- package/dist/Password.d.ts.map +1 -1
- package/dist/Password.js +397 -8
- package/dist/Password.js.map +1 -1
- package/dist/RecoveryCode.d.ts +169 -0
- package/dist/RecoveryCode.d.ts.map +1 -0
- package/dist/RecoveryCode.js +299 -0
- package/dist/RecoveryCode.js.map +1 -0
- package/dist/RefreshToken.d.ts +222 -0
- package/dist/RefreshToken.d.ts.map +1 -0
- package/dist/RefreshToken.js +342 -0
- package/dist/RefreshToken.js.map +1 -0
- package/dist/Sessions.d.ts +52 -2
- package/dist/Sessions.d.ts.map +1 -1
- package/dist/Sessions.js +123 -1
- package/dist/Sessions.js.map +1 -1
- package/dist/StepUp.d.ts +44 -0
- package/dist/StepUp.d.ts.map +1 -0
- package/dist/StepUp.js +82 -0
- package/dist/StepUp.js.map +1 -0
- package/dist/Storage.d.ts +14 -1
- package/dist/Storage.d.ts.map +1 -1
- package/dist/Storage.js.map +1 -1
- package/dist/StorageMigrations.d.ts +9 -1
- package/dist/StorageMigrations.d.ts.map +1 -1
- package/dist/StorageMigrations.js +159 -0
- package/dist/StorageMigrations.js.map +1 -1
- package/dist/Testing.d.ts +1 -1
- package/dist/Totp.d.ts +220 -0
- package/dist/Totp.d.ts.map +1 -0
- package/dist/Totp.js +477 -0
- package/dist/Totp.js.map +1 -0
- package/dist/TrustedDevice.d.ts +115 -0
- package/dist/TrustedDevice.d.ts.map +1 -0
- package/dist/TrustedDevice.js +222 -0
- package/dist/TrustedDevice.js.map +1 -0
- package/dist/alchemy/cloudflare/Email.d.ts +25 -0
- package/dist/alchemy/cloudflare/Email.d.ts.map +1 -0
- package/dist/alchemy/cloudflare/Email.js +117 -0
- package/dist/alchemy/cloudflare/Email.js.map +1 -0
- package/dist/cloudflare/Email.d.ts +25 -0
- package/dist/cloudflare/Email.d.ts.map +1 -0
- package/dist/cloudflare/Email.js +153 -0
- package/dist/cloudflare/Email.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/migrations/0003_auth_login_approval_review.sql +22 -0
- package/migrations/0004_auth_trusted_device.sql +12 -0
- package/migrations/0005_auth_passkey.sql +17 -0
- package/migrations/0006_auth_totp_factor.sql +17 -0
- package/migrations/0007_auth_recovery_code.sql +13 -0
- package/migrations/0008_auth_api_key.sql +17 -0
- package/migrations/0009_auth_refresh_token.sql +21 -0
- package/migrations/0010_auth_jwt_revocation.sql +8 -0
- package/package.json +57 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// oxlint-disable import(namespace): Schema.Codec is a type namespace exported by Effect.
|
|
2
|
+
import { Context, Data, Effect, Layer, Schema } from "effect";
|
|
3
|
+
export const LoginRiskLevelSchema = Schema.Literals([
|
|
4
|
+
"unknown",
|
|
5
|
+
"low",
|
|
6
|
+
"medium",
|
|
7
|
+
"high",
|
|
8
|
+
"critical",
|
|
9
|
+
]);
|
|
10
|
+
const LoginRiskMetadataSchema = Schema.Record(Schema.String, Schema.Unknown);
|
|
11
|
+
const loginRiskLevelRank = {
|
|
12
|
+
unknown: 0,
|
|
13
|
+
low: 1,
|
|
14
|
+
medium: 2,
|
|
15
|
+
high: 3,
|
|
16
|
+
critical: 4,
|
|
17
|
+
};
|
|
18
|
+
export class LoginRiskSignal extends Schema.Class("LoginRiskSignal")({
|
|
19
|
+
type: Schema.String,
|
|
20
|
+
level: Schema.optional(LoginRiskLevelSchema),
|
|
21
|
+
metadata: Schema.optional(LoginRiskMetadataSchema),
|
|
22
|
+
}) {
|
|
23
|
+
}
|
|
24
|
+
export const isLoginRiskSignal = Schema.is(LoginRiskSignal);
|
|
25
|
+
export class LoginRiskContext extends Schema.Class("LoginRiskContext")({
|
|
26
|
+
level: LoginRiskLevelSchema,
|
|
27
|
+
signals: Schema.Array(LoginRiskSignal),
|
|
28
|
+
metadata: Schema.optional(LoginRiskMetadataSchema),
|
|
29
|
+
}) {
|
|
30
|
+
hasSignal(type) {
|
|
31
|
+
return this.signals.some((signal) => signal.type === type);
|
|
32
|
+
}
|
|
33
|
+
getSignal(type) {
|
|
34
|
+
return this.signals.find((signal) => signal.type === type);
|
|
35
|
+
}
|
|
36
|
+
isAtLeast(level) {
|
|
37
|
+
return loginRiskLevelRank[this.level] >= loginRiskLevelRank[level];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export const isLoginRiskContext = Schema.is(LoginRiskContext);
|
|
41
|
+
export class LoginRiskError extends Data.TaggedError("LoginRiskError") {
|
|
42
|
+
}
|
|
43
|
+
export class LoginRiskEngine extends Context.Service()("auth/LoginRiskEngine") {
|
|
44
|
+
}
|
|
45
|
+
(function (LoginRiskEngine) {
|
|
46
|
+
LoginRiskEngine.make = (service) => LoginRiskEngine.of(service);
|
|
47
|
+
LoginRiskEngine.custom = (assess) => LoginRiskEngine.of({ assess });
|
|
48
|
+
})(LoginRiskEngine || (LoginRiskEngine = {}));
|
|
49
|
+
export const defaultLoginRiskContext = LoginRiskContext.make({
|
|
50
|
+
level: "unknown",
|
|
51
|
+
signals: [],
|
|
52
|
+
});
|
|
53
|
+
export const makeLoginRiskEngineNoop = () => LoginRiskEngine.make({
|
|
54
|
+
assess: () => Effect.succeed(defaultLoginRiskContext),
|
|
55
|
+
});
|
|
56
|
+
export const LoginRiskEngineNoopLive = Layer.succeed(LoginRiskEngine, makeLoginRiskEngineNoop());
|
|
57
|
+
//# sourceMappingURL=LoginRisk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginRisk.js","sourceRoot":"","sources":["../src/LoginRisk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Context, Duration, Effect, Layer, Redacted } from "effect";
|
|
2
|
+
import { AuthFlow } from "./AuthFlow.js";
|
|
3
|
+
import type { AuthFlowPrimaryFactorResult, AuthFlowService, AuthResultOf } from "./AuthFlow.js";
|
|
4
|
+
import { Challenge } from "./Challenge.js";
|
|
5
|
+
import type { ChallengeService } from "./Challenge.js";
|
|
6
|
+
import { Crypto } from "./Crypto.js";
|
|
7
|
+
import type { CryptoService } from "./Crypto.js";
|
|
8
|
+
import type { ChallengeId, UnixMillis } from "./Identifiers.js";
|
|
9
|
+
import { Email } from "./Identifiers.js";
|
|
10
|
+
import type { LoginRequestContext } from "./LoginRisk.js";
|
|
11
|
+
import { AuthMailer } from "./Mailer.js";
|
|
12
|
+
import type { AuthMailerService } from "./Mailer.js";
|
|
13
|
+
import { UserStore } from "./Storage.js";
|
|
14
|
+
import type { UserStoreService } from "./Storage.js";
|
|
15
|
+
export interface MagicLinkStartInput {
|
|
16
|
+
readonly email: Email;
|
|
17
|
+
readonly secret?: Redacted.Redacted<string>;
|
|
18
|
+
readonly ttl?: Duration.Duration;
|
|
19
|
+
readonly locale?: string;
|
|
20
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
21
|
+
}
|
|
22
|
+
export interface MagicLinkStarted {
|
|
23
|
+
readonly challengeId: ChallengeId;
|
|
24
|
+
readonly email: Email;
|
|
25
|
+
readonly expiresAt: UnixMillis;
|
|
26
|
+
}
|
|
27
|
+
export interface MagicLinkVerifyInput {
|
|
28
|
+
readonly challengeId: ChallengeId;
|
|
29
|
+
readonly secret: Redacted.Redacted<string>;
|
|
30
|
+
readonly trustedDeviceToken?: Redacted.Redacted<string>;
|
|
31
|
+
readonly request?: LoginRequestContext;
|
|
32
|
+
}
|
|
33
|
+
export interface MagicLinkUrlInput extends MagicLinkStarted {
|
|
34
|
+
readonly secret: Redacted.Redacted<string>;
|
|
35
|
+
readonly locale?: string;
|
|
36
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
37
|
+
}
|
|
38
|
+
declare const MagicLinkStartError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
39
|
+
readonly _tag: "MagicLinkStartError";
|
|
40
|
+
} & Readonly<A>;
|
|
41
|
+
export declare class MagicLinkStartError extends MagicLinkStartError_base<{
|
|
42
|
+
readonly message: string;
|
|
43
|
+
readonly cause?: unknown;
|
|
44
|
+
}> {
|
|
45
|
+
}
|
|
46
|
+
declare const MagicLinkVerifyError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
47
|
+
readonly _tag: "MagicLinkVerifyError";
|
|
48
|
+
} & Readonly<A>;
|
|
49
|
+
export declare class MagicLinkVerifyError extends MagicLinkVerifyError_base<{
|
|
50
|
+
readonly message: string;
|
|
51
|
+
readonly cause?: unknown;
|
|
52
|
+
}> {
|
|
53
|
+
}
|
|
54
|
+
export type MagicLinkError = MagicLinkStartError | MagicLinkVerifyError;
|
|
55
|
+
export type MagicLinkVerifyResult = AuthFlowPrimaryFactorResult<"magic-link"> | AuthResultOf<"InvalidCredentials" | "AccountDisabled">;
|
|
56
|
+
export interface MagicLinkLoginService {
|
|
57
|
+
readonly start: (input: MagicLinkStartInput) => Effect.Effect<MagicLinkStarted, MagicLinkStartError>;
|
|
58
|
+
readonly verify: (input: MagicLinkVerifyInput) => Effect.Effect<MagicLinkVerifyResult, MagicLinkVerifyError>;
|
|
59
|
+
}
|
|
60
|
+
declare const MagicLinkLogin_base: Context.ServiceClass<MagicLinkLogin, "auth/login/MagicLink", MagicLinkLoginService>;
|
|
61
|
+
export declare class MagicLinkLogin extends MagicLinkLogin_base {
|
|
62
|
+
}
|
|
63
|
+
export declare namespace MagicLinkLogin {
|
|
64
|
+
const make: (service: MagicLinkLoginService) => MagicLinkLoginService;
|
|
65
|
+
}
|
|
66
|
+
export interface MagicLinkOptions {
|
|
67
|
+
readonly ttl?: Duration.Duration;
|
|
68
|
+
readonly secretBytes?: number;
|
|
69
|
+
readonly userIdBytes?: number;
|
|
70
|
+
readonly makeUrl: (input: MagicLinkUrlInput) => string;
|
|
71
|
+
}
|
|
72
|
+
export interface MagicLinkDependencies extends MagicLinkOptions {
|
|
73
|
+
readonly challenge: ChallengeService;
|
|
74
|
+
readonly users: UserStoreService;
|
|
75
|
+
readonly crypto: CryptoService;
|
|
76
|
+
readonly authFlow: AuthFlowService;
|
|
77
|
+
readonly authMailer: AuthMailerService;
|
|
78
|
+
}
|
|
79
|
+
export declare const defaultMagicLinkTtl: Duration.Duration;
|
|
80
|
+
export declare const defaultMagicLinkSecretBytes = 32;
|
|
81
|
+
export declare const makeMagicLinkLogin: (dependencies: MagicLinkDependencies) => MagicLinkLoginService;
|
|
82
|
+
export declare const MagicLinkLoginLive: (options: MagicLinkOptions) => Layer.Layer<MagicLinkLogin, never, Crypto | UserStore | AuthMailer | Challenge | AuthFlow>;
|
|
83
|
+
export declare const MagicLinkFeatureLive: (options: MagicLinkOptions) => Layer.Layer<MagicLinkLogin, never, Crypto | UserStore | AuthMailer | Challenge | AuthFlow>;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=MagicLink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MagicLink.d.ts","sourceRoot":"","sources":["../src/MagicLink.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { Context, Data, Duration, Effect, Layer, Option, Redacted } from "effect";
|
|
2
|
+
import { AuthFlow, AuthResult } from "./AuthFlow.js";
|
|
3
|
+
import { Challenge } from "./Challenge.js";
|
|
4
|
+
import { Crypto } from "./Crypto.js";
|
|
5
|
+
import { Email, UserId } from "./Identifiers.js";
|
|
6
|
+
import { currentUnixMillis } from "./Internal.js";
|
|
7
|
+
import { AuthMailer } from "./Mailer.js";
|
|
8
|
+
import { UserStore } from "./Storage.js";
|
|
9
|
+
export class MagicLinkStartError extends Data.TaggedError("MagicLinkStartError") {
|
|
10
|
+
}
|
|
11
|
+
export class MagicLinkVerifyError extends Data.TaggedError("MagicLinkVerifyError") {
|
|
12
|
+
}
|
|
13
|
+
export class MagicLinkLogin extends Context.Service()("auth/login/MagicLink") {
|
|
14
|
+
}
|
|
15
|
+
(function (MagicLinkLogin) {
|
|
16
|
+
MagicLinkLogin.make = (service) => MagicLinkLogin.of(service);
|
|
17
|
+
})(MagicLinkLogin || (MagicLinkLogin = {}));
|
|
18
|
+
export const defaultMagicLinkTtl = Duration.minutes(15);
|
|
19
|
+
export const defaultMagicLinkSecretBytes = 32;
|
|
20
|
+
const verifiedExistingUser = (users, user) => Effect.gen(function* () {
|
|
21
|
+
if (user.disabledAt !== undefined) {
|
|
22
|
+
return AuthResult.AccountDisabled();
|
|
23
|
+
}
|
|
24
|
+
if (user.emailVerified) {
|
|
25
|
+
return { _tag: "User", user };
|
|
26
|
+
}
|
|
27
|
+
const updatedAt = yield* currentUnixMillis;
|
|
28
|
+
const updated = yield* users
|
|
29
|
+
.markEmailVerified({ userId: user.id, updatedAt })
|
|
30
|
+
.pipe(Effect.mapError((cause) => new MagicLinkVerifyError({
|
|
31
|
+
message: "Failed to mark email verified",
|
|
32
|
+
cause,
|
|
33
|
+
})));
|
|
34
|
+
if (Option.isNone(updated)) {
|
|
35
|
+
return yield* new MagicLinkVerifyError({ message: "User not found" });
|
|
36
|
+
}
|
|
37
|
+
return { _tag: "User", user: updated.value };
|
|
38
|
+
});
|
|
39
|
+
const findByEmail = (users, email) => users.findByEmail(email).pipe(Effect.mapError((cause) => new MagicLinkVerifyError({
|
|
40
|
+
message: "Failed to load user by email",
|
|
41
|
+
cause,
|
|
42
|
+
})));
|
|
43
|
+
const createVerifiedUser = (dependencies, email) => Effect.gen(function* () {
|
|
44
|
+
const now = yield* currentUnixMillis;
|
|
45
|
+
const userId = UserId(yield* dependencies.crypto
|
|
46
|
+
.randomToken(dependencies.userIdBytes ?? 16)
|
|
47
|
+
.pipe(Effect.mapError((cause) => new MagicLinkVerifyError({
|
|
48
|
+
message: "Failed to generate user id",
|
|
49
|
+
cause,
|
|
50
|
+
}))));
|
|
51
|
+
const user = {
|
|
52
|
+
id: userId,
|
|
53
|
+
email,
|
|
54
|
+
emailVerified: true,
|
|
55
|
+
createdAt: now,
|
|
56
|
+
updatedAt: now,
|
|
57
|
+
};
|
|
58
|
+
return yield* dependencies.users.insert(user).pipe(Effect.as({ _tag: "User", user }), Effect.catchTag("StorageError", (cause) => findByEmail(dependencies.users, email).pipe(Effect.flatMap((existing) => Option.isSome(existing)
|
|
59
|
+
? verifiedExistingUser(dependencies.users, existing.value)
|
|
60
|
+
: Effect.fail(new MagicLinkVerifyError({
|
|
61
|
+
message: "Failed to create user",
|
|
62
|
+
cause,
|
|
63
|
+
}))))));
|
|
64
|
+
});
|
|
65
|
+
const findOrCreateVerifiedUser = (dependencies, email) => Effect.gen(function* () {
|
|
66
|
+
const existing = yield* findByEmail(dependencies.users, email);
|
|
67
|
+
if (Option.isSome(existing)) {
|
|
68
|
+
return yield* verifiedExistingUser(dependencies.users, existing.value);
|
|
69
|
+
}
|
|
70
|
+
return yield* createVerifiedUser(dependencies, email);
|
|
71
|
+
});
|
|
72
|
+
const invalidateChallenge = (challenge, id) => challenge
|
|
73
|
+
.consume(id)
|
|
74
|
+
.pipe(Effect.catchTag("ChallengeConsumeError", () => Effect.void));
|
|
75
|
+
const startSecret = (crypto, input, secretBytes) => {
|
|
76
|
+
if (input.secret !== undefined) {
|
|
77
|
+
return Effect.succeed(Redacted.make(Redacted.value(input.secret).trim()));
|
|
78
|
+
}
|
|
79
|
+
return crypto.randomToken(secretBytes).pipe(Effect.map(Redacted.make), Effect.mapError((cause) => new MagicLinkStartError({
|
|
80
|
+
message: "Failed to generate magic link secret",
|
|
81
|
+
cause,
|
|
82
|
+
})));
|
|
83
|
+
};
|
|
84
|
+
const makeMagicLinkUrl = (dependencies, input) => Effect.try({
|
|
85
|
+
try: () => dependencies.makeUrl(input),
|
|
86
|
+
catch: (cause) => new MagicLinkStartError({
|
|
87
|
+
message: "Failed to build magic link URL",
|
|
88
|
+
cause,
|
|
89
|
+
}),
|
|
90
|
+
});
|
|
91
|
+
const verifySecret = (secret) => Redacted.make(Redacted.value(secret).trim());
|
|
92
|
+
export const makeMagicLinkLogin = (dependencies) => {
|
|
93
|
+
const ttl = dependencies.ttl ?? defaultMagicLinkTtl;
|
|
94
|
+
const secretBytes = dependencies.secretBytes ?? defaultMagicLinkSecretBytes;
|
|
95
|
+
return MagicLinkLogin.make({
|
|
96
|
+
start: Effect.fn("auth.magic_link.start")(function* (input) {
|
|
97
|
+
yield* Effect.annotateCurrentSpan("auth.method", "magic-link");
|
|
98
|
+
const secret = yield* startSecret(dependencies.crypto, input, secretBytes);
|
|
99
|
+
const issued = yield* dependencies.challenge
|
|
100
|
+
.issue({
|
|
101
|
+
type: "magic-link",
|
|
102
|
+
subject: input.email,
|
|
103
|
+
ttl: input.ttl ?? ttl,
|
|
104
|
+
secret,
|
|
105
|
+
metadata: input.metadata,
|
|
106
|
+
})
|
|
107
|
+
.pipe(Effect.mapError((cause) => new MagicLinkStartError({
|
|
108
|
+
message: "Failed to issue magic link challenge",
|
|
109
|
+
cause,
|
|
110
|
+
})));
|
|
111
|
+
const started = {
|
|
112
|
+
challengeId: issued.id,
|
|
113
|
+
email: input.email,
|
|
114
|
+
expiresAt: issued.expiresAt,
|
|
115
|
+
};
|
|
116
|
+
const url = yield* makeMagicLinkUrl(dependencies, {
|
|
117
|
+
...started,
|
|
118
|
+
secret,
|
|
119
|
+
locale: input.locale,
|
|
120
|
+
metadata: input.metadata,
|
|
121
|
+
}).pipe(Effect.matchEffect({
|
|
122
|
+
onSuccess: Effect.succeed,
|
|
123
|
+
onFailure: (error) => invalidateChallenge(dependencies.challenge, issued.id).pipe(Effect.flatMap(() => Effect.fail(error))),
|
|
124
|
+
}));
|
|
125
|
+
yield* dependencies.authMailer
|
|
126
|
+
.send({
|
|
127
|
+
_tag: "MagicLink",
|
|
128
|
+
to: input.email,
|
|
129
|
+
challengeId: issued.id,
|
|
130
|
+
url,
|
|
131
|
+
expiresAt: issued.expiresAt,
|
|
132
|
+
locale: input.locale,
|
|
133
|
+
metadata: input.metadata,
|
|
134
|
+
})
|
|
135
|
+
.pipe(Effect.matchEffect({
|
|
136
|
+
onSuccess: () => Effect.void,
|
|
137
|
+
onFailure: (cause) => invalidateChallenge(dependencies.challenge, issued.id).pipe(Effect.flatMap(() => Effect.fail(new MagicLinkStartError({
|
|
138
|
+
message: "Failed to send magic link",
|
|
139
|
+
cause,
|
|
140
|
+
})))),
|
|
141
|
+
}));
|
|
142
|
+
return started;
|
|
143
|
+
}),
|
|
144
|
+
verify: Effect.fn("auth.magic_link.verify")(function* (input) {
|
|
145
|
+
yield* Effect.annotateCurrentSpan("auth.method", "magic-link");
|
|
146
|
+
const verifiedOption = yield* dependencies.challenge
|
|
147
|
+
.verify({
|
|
148
|
+
challengeId: input.challengeId,
|
|
149
|
+
type: "magic-link",
|
|
150
|
+
secret: verifySecret(input.secret),
|
|
151
|
+
})
|
|
152
|
+
.pipe(Effect.match({
|
|
153
|
+
onSuccess: Option.some,
|
|
154
|
+
onFailure: () => Option.none(),
|
|
155
|
+
}));
|
|
156
|
+
if (Option.isNone(verifiedOption)) {
|
|
157
|
+
yield* Effect.annotateCurrentSpan("auth.result", "InvalidCredentials");
|
|
158
|
+
return AuthResult.InvalidCredentials();
|
|
159
|
+
}
|
|
160
|
+
const email = Email(verifiedOption.value.subject);
|
|
161
|
+
const userResult = yield* findOrCreateVerifiedUser(dependencies, email);
|
|
162
|
+
if (userResult._tag === "AccountDisabled") {
|
|
163
|
+
yield* Effect.annotateCurrentSpan("auth.result", "AccountDisabled");
|
|
164
|
+
return userResult;
|
|
165
|
+
}
|
|
166
|
+
return yield* dependencies.authFlow
|
|
167
|
+
.completePrimaryFactor({
|
|
168
|
+
userId: userResult.user.id,
|
|
169
|
+
email: userResult.user.email,
|
|
170
|
+
intent: "sign-in",
|
|
171
|
+
method: "magic-link",
|
|
172
|
+
amr: ["email", "link"],
|
|
173
|
+
aal: "aal1",
|
|
174
|
+
claims: { emailVerified: true },
|
|
175
|
+
...(input.trustedDeviceToken === undefined
|
|
176
|
+
? {}
|
|
177
|
+
: { trustedDeviceToken: input.trustedDeviceToken }),
|
|
178
|
+
...(input.request === undefined ? {} : { request: input.request }),
|
|
179
|
+
...(verifiedOption.value.metadata === undefined
|
|
180
|
+
? {}
|
|
181
|
+
: { metadata: verifiedOption.value.metadata }),
|
|
182
|
+
})
|
|
183
|
+
.pipe(Effect.mapError((cause) => new MagicLinkVerifyError({
|
|
184
|
+
message: "Failed to complete magic link authentication",
|
|
185
|
+
cause,
|
|
186
|
+
})));
|
|
187
|
+
}),
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
export const MagicLinkLoginLive = (options) => Layer.effect(MagicLinkLogin)(Effect.gen(function* () {
|
|
191
|
+
const challenge = yield* Challenge;
|
|
192
|
+
const users = yield* UserStore;
|
|
193
|
+
const crypto = yield* Crypto;
|
|
194
|
+
const authFlow = yield* AuthFlow;
|
|
195
|
+
const authMailer = yield* AuthMailer;
|
|
196
|
+
return makeMagicLinkLogin({
|
|
197
|
+
...options,
|
|
198
|
+
challenge,
|
|
199
|
+
users,
|
|
200
|
+
crypto,
|
|
201
|
+
authFlow,
|
|
202
|
+
authMailer,
|
|
203
|
+
});
|
|
204
|
+
}));
|
|
205
|
+
export const MagicLinkFeatureLive = MagicLinkLoginLive;
|
|
206
|
+
//# sourceMappingURL=MagicLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MagicLink.js","sourceRoot":"","sources":["../src/MagicLink.ts"],"names":[],"mappings":"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"}
|
package/dist/Mailer.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context, Effect, Layer, Redacted } from "effect";
|
|
2
|
-
import type { ChallengeId, Email, UnixMillis, UserId } from "./Identifiers.js";
|
|
2
|
+
import type { ChallengeId, Email, SessionId, UnixMillis, UserId } from "./Identifiers.js";
|
|
3
|
+
import type { LoginRequestContext } from "./LoginRisk.js";
|
|
3
4
|
export type EmailAddress = Email | {
|
|
4
5
|
readonly email: Email;
|
|
5
6
|
readonly name?: string;
|
|
@@ -50,6 +51,12 @@ export interface AuthMagicLinkEmail extends AuthEmailBase {
|
|
|
50
51
|
readonly url: string;
|
|
51
52
|
readonly expiresAt: UnixMillis;
|
|
52
53
|
}
|
|
54
|
+
export interface AuthPasswordResetEmail extends AuthEmailBase {
|
|
55
|
+
readonly _tag: "PasswordReset";
|
|
56
|
+
readonly challengeId: ChallengeId;
|
|
57
|
+
readonly url: string;
|
|
58
|
+
readonly expiresAt: UnixMillis;
|
|
59
|
+
}
|
|
53
60
|
export interface AuthEmailVerificationEmail extends AuthEmailBase {
|
|
54
61
|
readonly _tag: "EmailVerification";
|
|
55
62
|
readonly challengeId: ChallengeId;
|
|
@@ -58,7 +65,31 @@ export interface AuthEmailVerificationEmail extends AuthEmailBase {
|
|
|
58
65
|
readonly url?: string;
|
|
59
66
|
readonly expiresAt: UnixMillis;
|
|
60
67
|
}
|
|
61
|
-
export
|
|
68
|
+
export interface AuthLoginApprovalEmail extends AuthEmailBase {
|
|
69
|
+
readonly _tag: "LoginApproval";
|
|
70
|
+
readonly challengeId: ChallengeId;
|
|
71
|
+
readonly userId: UserId;
|
|
72
|
+
readonly secret?: Redacted.Redacted<string>;
|
|
73
|
+
readonly url?: string;
|
|
74
|
+
readonly expiresAt: UnixMillis;
|
|
75
|
+
readonly reason: string;
|
|
76
|
+
readonly sessionBinding: "originating-device" | "approval-device" | "none";
|
|
77
|
+
readonly sameDeviceRequired: boolean;
|
|
78
|
+
}
|
|
79
|
+
export interface AuthLoginNotificationEmail extends AuthEmailBase {
|
|
80
|
+
readonly _tag: "LoginNotification";
|
|
81
|
+
readonly userId: UserId;
|
|
82
|
+
readonly sessionId: SessionId;
|
|
83
|
+
readonly method: string;
|
|
84
|
+
readonly reason: string;
|
|
85
|
+
readonly deviceStatus: string;
|
|
86
|
+
readonly request?: LoginRequestContext;
|
|
87
|
+
readonly occurredAt: UnixMillis;
|
|
88
|
+
readonly reportChallengeId?: ChallengeId;
|
|
89
|
+
readonly reportUrl?: string;
|
|
90
|
+
readonly reportExpiresAt?: UnixMillis;
|
|
91
|
+
}
|
|
92
|
+
export type AuthEmail = AuthEmailOtp | AuthMagicLinkEmail | AuthPasswordResetEmail | AuthEmailVerificationEmail | AuthLoginApprovalEmail | AuthLoginNotificationEmail;
|
|
62
93
|
export interface RenderedEmail {
|
|
63
94
|
readonly from?: EmailAddress;
|
|
64
95
|
readonly subject: string;
|
package/dist/Mailer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mailer.d.ts","sourceRoot":"","sources":["../src/Mailer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Mailer.d.ts","sourceRoot":"","sources":["../src/Mailer.ts"],"names":[],"mappings":"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"}
|
package/dist/Mailer.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// oxlint-disable complexity
|
|
1
2
|
import { Context, Data, Effect, Layer, Redacted } from "effect";
|
|
2
3
|
export class EmailSendError extends Data.TaggedError("EmailSendError") {
|
|
3
4
|
}
|
|
@@ -21,6 +22,58 @@ export class AuthMailer extends Context.Service()("auth/AuthMailer") {
|
|
|
21
22
|
AuthMailer.make = (service) => AuthMailer.of(service);
|
|
22
23
|
})(AuthMailer || (AuthMailer = {}));
|
|
23
24
|
const expiresAtText = (expiresAt) => new Date(Number(expiresAt)).toISOString();
|
|
25
|
+
const deviceStatusText = (status) => {
|
|
26
|
+
switch (status) {
|
|
27
|
+
case "known": {
|
|
28
|
+
return "Recognized device";
|
|
29
|
+
}
|
|
30
|
+
case "new":
|
|
31
|
+
case "unknown": {
|
|
32
|
+
return "Unrecognized device";
|
|
33
|
+
}
|
|
34
|
+
default: {
|
|
35
|
+
return status;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const browserName = (userAgent) => {
|
|
40
|
+
if (userAgent.includes("Edg/")) {
|
|
41
|
+
return "Edge";
|
|
42
|
+
}
|
|
43
|
+
if (userAgent.includes("Chrome/") || userAgent.includes("CriOS/")) {
|
|
44
|
+
return "Chrome";
|
|
45
|
+
}
|
|
46
|
+
if (userAgent.includes("Firefox/") || userAgent.includes("FxiOS/")) {
|
|
47
|
+
return "Firefox";
|
|
48
|
+
}
|
|
49
|
+
if (userAgent.includes("Safari/") && userAgent.includes("Version/")) {
|
|
50
|
+
return "Safari";
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
};
|
|
54
|
+
const osName = (userAgent) => {
|
|
55
|
+
if (userAgent.includes("Windows NT")) {
|
|
56
|
+
return "Windows";
|
|
57
|
+
}
|
|
58
|
+
if (userAgent.includes("Mac OS X")) {
|
|
59
|
+
return userAgent.includes("Mobile/") ? "iOS" : "macOS";
|
|
60
|
+
}
|
|
61
|
+
if (userAgent.includes("Android")) {
|
|
62
|
+
return "Android";
|
|
63
|
+
}
|
|
64
|
+
if (userAgent.includes("Linux")) {
|
|
65
|
+
return "Linux";
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
};
|
|
69
|
+
const userAgentSummary = (userAgent) => {
|
|
70
|
+
const browser = browserName(userAgent);
|
|
71
|
+
const os = osName(userAgent);
|
|
72
|
+
if (browser !== undefined && os !== undefined) {
|
|
73
|
+
return `${browser} on ${os}`;
|
|
74
|
+
}
|
|
75
|
+
return browser ?? os ?? userAgent;
|
|
76
|
+
};
|
|
24
77
|
export const makeDefaultAuthEmailTemplates = () => AuthEmailTemplates.make({
|
|
25
78
|
render: Effect.fn("auth.email_templates.default.render")(function* (input) {
|
|
26
79
|
switch (input._tag) {
|
|
@@ -37,6 +90,12 @@ export const makeDefaultAuthEmailTemplates = () => AuthEmailTemplates.make({
|
|
|
37
90
|
text: `Use this link to sign in:\n\n${input.url}\n\nThis link expires at ${expiresAtText(input.expiresAt)}.`,
|
|
38
91
|
};
|
|
39
92
|
}
|
|
93
|
+
case "PasswordReset": {
|
|
94
|
+
return {
|
|
95
|
+
subject: "Reset your password",
|
|
96
|
+
text: `Use this link to reset your password:\n\n${input.url}\n\nThis link expires at ${expiresAtText(input.expiresAt)}.`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
40
99
|
case "EmailVerification": {
|
|
41
100
|
if (input.url !== undefined) {
|
|
42
101
|
return {
|
|
@@ -56,6 +115,54 @@ export const makeDefaultAuthEmailTemplates = () => AuthEmailTemplates.make({
|
|
|
56
115
|
text: `Use the email verification request before ${expiresAtText(input.expiresAt)}.`,
|
|
57
116
|
};
|
|
58
117
|
}
|
|
118
|
+
case "LoginApproval": {
|
|
119
|
+
if (input.url !== undefined) {
|
|
120
|
+
return {
|
|
121
|
+
subject: "Approve your sign-in",
|
|
122
|
+
text: `Use this link to approve your sign-in:\n\n${input.url}\n\nThis approval expires at ${expiresAtText(input.expiresAt)}.`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (input.secret !== undefined) {
|
|
126
|
+
const code = Redacted.value(input.secret);
|
|
127
|
+
return {
|
|
128
|
+
subject: "Approve your sign-in",
|
|
129
|
+
text: `Your sign-in approval code is ${code}.\n\nThis code expires at ${expiresAtText(input.expiresAt)}.`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
subject: "Approve your sign-in",
|
|
134
|
+
text: `Use the sign-in approval request before ${expiresAtText(input.expiresAt)}.`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
case "LoginNotification": {
|
|
138
|
+
const location = [
|
|
139
|
+
input.request?.city,
|
|
140
|
+
input.request?.region,
|
|
141
|
+
input.request?.country,
|
|
142
|
+
]
|
|
143
|
+
.filter((part) => part !== undefined && part.length > 0)
|
|
144
|
+
.join(", ");
|
|
145
|
+
const details = [
|
|
146
|
+
`Method: ${input.method}`,
|
|
147
|
+
`Device: ${deviceStatusText(input.deviceStatus)}`,
|
|
148
|
+
input.request?.ip === undefined
|
|
149
|
+
? undefined
|
|
150
|
+
: `IP: ${input.request.ip}`,
|
|
151
|
+
input.request?.userAgent === undefined
|
|
152
|
+
? undefined
|
|
153
|
+
: `Browser: ${userAgentSummary(input.request.userAgent)}`,
|
|
154
|
+
location.length === 0 ? undefined : `Location: ${location}`,
|
|
155
|
+
]
|
|
156
|
+
.filter((part) => part !== undefined)
|
|
157
|
+
.join("\n");
|
|
158
|
+
const reportText = input.reportUrl === undefined
|
|
159
|
+
? "If this was you, no action is needed."
|
|
160
|
+
: `If this was you, no action is needed. If this wasn't you, secure your account here:\n\n${input.reportUrl}\n\nThis link expires at ${expiresAtText(input.reportExpiresAt ?? input.occurredAt)}.`;
|
|
161
|
+
return {
|
|
162
|
+
subject: "New sign-in to your account",
|
|
163
|
+
text: `We noticed a new sign-in to your account at ${expiresAtText(input.occurredAt)}.\n\n${details}\n\n${reportText}`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
59
166
|
}
|
|
60
167
|
}),
|
|
61
168
|
});
|
package/dist/Mailer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mailer.js","sourceRoot":"","sources":["../src/Mailer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"Mailer.js","sourceRoot":"","sources":["../src/Mailer.ts"],"names":[],"mappings":"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"}
|