@shivaedev/identity 0.0.0 → 0.2.0
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/LICENSE +21 -0
- package/README.md +516 -1
- package/dist/identity.d.ts +36 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +12 -0
- package/dist/identity.js.map +1 -0
- package/dist/middleware.d.ts +21 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +20 -0
- package/dist/middleware.js.map +1 -0
- package/dist/permission.d.ts +11 -0
- package/dist/permission.d.ts.map +1 -0
- package/dist/permission.js +17 -0
- package/dist/permission.js.map +1 -0
- package/dist/server/adapters/betterAuthSessions.d.ts +14 -0
- package/dist/server/adapters/betterAuthSessions.d.ts.map +1 -0
- package/dist/server/adapters/betterAuthSessions.js +24 -0
- package/dist/server/adapters/betterAuthSessions.js.map +1 -0
- package/dist/server/better-auth/allowedAccounts.d.ts +10 -0
- package/dist/server/better-auth/allowedAccounts.d.ts.map +1 -0
- package/dist/server/better-auth/allowedAccounts.js +20 -0
- package/dist/server/better-auth/allowedAccounts.js.map +1 -0
- package/dist/server/better-auth/bearerSessions.d.ts +9 -0
- package/dist/server/better-auth/bearerSessions.d.ts.map +1 -0
- package/dist/server/better-auth/bearerSessions.js +38 -0
- package/dist/server/better-auth/bearerSessions.js.map +1 -0
- package/dist/server/better-auth/clientIp.d.ts +8 -0
- package/dist/server/better-auth/clientIp.d.ts.map +1 -0
- package/dist/server/better-auth/clientIp.js +28 -0
- package/dist/server/better-auth/clientIp.js.map +1 -0
- package/dist/server/better-auth/memoryRateLimit.d.ts +3 -0
- package/dist/server/better-auth/memoryRateLimit.d.ts.map +1 -0
- package/dist/server/better-auth/memoryRateLimit.js +46 -0
- package/dist/server/better-auth/memoryRateLimit.js.map +1 -0
- package/dist/server/better-auth/mount.d.ts +265 -0
- package/dist/server/better-auth/mount.d.ts.map +1 -0
- package/dist/server/better-auth/mount.js +111 -0
- package/dist/server/better-auth/mount.js.map +1 -0
- package/dist/server/better-auth/mountRoutes.d.ts +23 -0
- package/dist/server/better-auth/mountRoutes.d.ts.map +1 -0
- package/dist/server/better-auth/mountRoutes.js +51 -0
- package/dist/server/better-auth/mountRoutes.js.map +1 -0
- package/dist/server/better-auth/mountedSessions.d.ts +15 -0
- package/dist/server/better-auth/mountedSessions.d.ts.map +1 -0
- package/dist/server/better-auth/mountedSessions.js +12 -0
- package/dist/server/better-auth/mountedSessions.js.map +1 -0
- package/dist/server/better-auth/revokeUnadmitted.d.ts +10 -0
- package/dist/server/better-auth/revokeUnadmitted.d.ts.map +1 -0
- package/dist/server/better-auth/revokeUnadmitted.js +29 -0
- package/dist/server/better-auth/revokeUnadmitted.js.map +1 -0
- package/dist/server/better-auth/sessionPermissions.d.ts +3 -0
- package/dist/server/better-auth/sessionPermissions.d.ts.map +1 -0
- package/dist/server/better-auth/sessionPermissions.js +16 -0
- package/dist/server/better-auth/sessionPermissions.js.map +1 -0
- package/dist/server/better-auth/signInGate.d.ts +37 -0
- package/dist/server/better-auth/signInGate.d.ts.map +1 -0
- package/dist/server/better-auth/signInGate.js +38 -0
- package/dist/server/better-auth/signInGate.js.map +1 -0
- package/dist/server/better-auth/signInPolicy.d.ts +193 -0
- package/dist/server/better-auth/signInPolicy.d.ts.map +1 -0
- package/dist/server/better-auth/signInPolicy.js +61 -0
- package/dist/server/better-auth/signInPolicy.js.map +1 -0
- package/dist/server/better-auth/testDatabase.d.ts +19 -0
- package/dist/server/better-auth/testDatabase.d.ts.map +1 -0
- package/dist/server/better-auth/testDatabase.js +24 -0
- package/dist/server/better-auth/testDatabase.js.map +1 -0
- package/dist/server/better-auth/testing.d.ts +24 -0
- package/dist/server/better-auth/testing.d.ts.map +1 -0
- package/dist/server/better-auth/testing.js +21 -0
- package/dist/server/better-auth/testing.js.map +1 -0
- package/dist/server/better-auth/userProfiles.d.ts +14 -0
- package/dist/server/better-auth/userProfiles.d.ts.map +1 -0
- package/dist/server/better-auth/userProfiles.js +20 -0
- package/dist/server/better-auth/userProfiles.js.map +1 -0
- package/dist/server/commandChanges.d.ts +5 -0
- package/dist/server/commandChanges.d.ts.map +1 -0
- package/dist/server/commandChanges.js +44 -0
- package/dist/server/commandChanges.js.map +1 -0
- package/dist/server/local.d.ts +10 -0
- package/dist/server/local.d.ts.map +1 -0
- package/dist/server/local.js +93 -0
- package/dist/server/local.js.map +1 -0
- package/dist/server/origin.d.ts +15 -0
- package/dist/server/origin.d.ts.map +1 -0
- package/dist/server/origin.js +16 -0
- package/dist/server/origin.js.map +1 -0
- package/dist/server/permissions.d.ts +9 -0
- package/dist/server/permissions.d.ts.map +1 -0
- package/dist/server/permissions.js +31 -0
- package/dist/server/permissions.js.map +1 -0
- package/dist/server/proxyRanges.d.ts +4 -0
- package/dist/server/proxyRanges.d.ts.map +1 -0
- package/dist/server/proxyRanges.js +62 -0
- package/dist/server/proxyRanges.js.map +1 -0
- package/dist/server/resolveRole.d.ts +11 -0
- package/dist/server/resolveRole.d.ts.map +1 -0
- package/dist/server/resolveRole.js +6 -0
- package/dist/server/resolveRole.js.map +1 -0
- package/dist/server/revalidateStream.d.ts +6 -0
- package/dist/server/revalidateStream.d.ts.map +1 -0
- package/dist/server/revalidateStream.js +19 -0
- package/dist/server/revalidateStream.js.map +1 -0
- package/dist/server/session.d.ts +39 -0
- package/dist/server/session.d.ts.map +1 -0
- package/dist/server/session.js +73 -0
- package/dist/server/session.js.map +1 -0
- package/dist/server/sessionKeys.d.ts +10 -0
- package/dist/server/sessionKeys.d.ts.map +1 -0
- package/dist/server/sessionKeys.js +22 -0
- package/dist/server/sessionKeys.js.map +1 -0
- package/dist/server/sessionProfile.d.ts +3 -0
- package/dist/server/sessionProfile.d.ts.map +1 -0
- package/dist/server/sessionProfile.js +4 -0
- package/dist/server/sessionProfile.js.map +1 -0
- package/dist/server/tracing.d.ts +9 -0
- package/dist/server/tracing.d.ts.map +1 -0
- package/dist/server/tracing.js +51 -0
- package/dist/server/tracing.js.map +1 -0
- package/dist/server/transportHeaders.d.ts +4 -0
- package/dist/server/transportHeaders.d.ts.map +1 -0
- package/dist/server/transportHeaders.js +6 -0
- package/dist/server/transportHeaders.js.map +1 -0
- package/dist/server/trustedProxy.d.ts +7 -0
- package/dist/server/trustedProxy.d.ts.map +1 -0
- package/dist/server/trustedProxy.js +19 -0
- package/dist/server/trustedProxy.js.map +1 -0
- package/dist/server/trustedProxyRanges.d.ts +2 -0
- package/dist/server/trustedProxyRanges.d.ts.map +1 -0
- package/dist/server/trustedProxyRanges.js +5 -0
- package/dist/server/trustedProxyRanges.js.map +1 -0
- package/package.json +86 -4
- package/src/identity.ts +26 -0
- package/src/middleware.ts +38 -0
- package/src/permission.ts +24 -0
- package/src/server/adapters/betterAuthSessions.ts +44 -0
- package/src/server/better-auth/allowedAccounts.ts +29 -0
- package/src/server/better-auth/bearerSessions.ts +50 -0
- package/src/server/better-auth/clientIp.ts +34 -0
- package/src/server/better-auth/memoryRateLimit.ts +56 -0
- package/src/server/better-auth/mount.ts +146 -0
- package/src/server/better-auth/mountRoutes.ts +73 -0
- package/src/server/better-auth/mountedSessions.ts +21 -0
- package/src/server/better-auth/revokeUnadmitted.ts +41 -0
- package/src/server/better-auth/sessionPermissions.ts +18 -0
- package/src/server/better-auth/signInGate.ts +77 -0
- package/src/server/better-auth/signInPolicy.ts +72 -0
- package/src/server/better-auth/testDatabase.ts +27 -0
- package/src/server/better-auth/testing.ts +35 -0
- package/src/server/better-auth/userProfiles.ts +37 -0
- package/src/server/commandChanges.ts +52 -0
- package/src/server/local.ts +100 -0
- package/src/server/origin.ts +26 -0
- package/src/server/permissions.ts +51 -0
- package/src/server/proxyRanges.ts +61 -0
- package/src/server/resolveRole.ts +7 -0
- package/src/server/revalidateStream.ts +25 -0
- package/src/server/session.ts +148 -0
- package/src/server/sessionKeys.ts +25 -0
- package/src/server/sessionProfile.ts +5 -0
- package/src/server/tracing.ts +68 -0
- package/src/server/transportHeaders.ts +8 -0
- package/src/server/trustedProxy.ts +22 -0
- package/src/server/trustedProxyRanges.ts +5 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { RpcMiddleware } from "effect/rpc";
|
|
3
|
+
import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
|
|
4
|
+
import type { Identity, OptionalIdentity, RequestId, SessionUser, SessionUserWithProviderAccounts } from "./identity.ts";
|
|
5
|
+
declare const RequestTracing_base: RpcMiddleware.ServiceClass<RequestTracing, "@shivaedev/identity/RequestTracing", RequestId, Schema.Never, never, never, false>;
|
|
6
|
+
export declare class RequestTracing extends RequestTracing_base {
|
|
7
|
+
}
|
|
8
|
+
declare const Authenticated_base: RpcMiddleware.ServiceClass<Authenticated, "@shivaedev/identity/Authenticated", Identity, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false>;
|
|
9
|
+
export declare class Authenticated extends Authenticated_base {
|
|
10
|
+
}
|
|
11
|
+
declare const MaybeAuthenticated_base: RpcMiddleware.ServiceClass<MaybeAuthenticated, "@shivaedev/identity/MaybeAuthenticated", OptionalIdentity, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false>;
|
|
12
|
+
export declare class MaybeAuthenticated extends MaybeAuthenticated_base {
|
|
13
|
+
}
|
|
14
|
+
declare const AuthenticatedUser_base: RpcMiddleware.ServiceClass<AuthenticatedUser, "@shivaedev/identity/AuthenticatedUser", Identity | SessionUser, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false>;
|
|
15
|
+
export declare class AuthenticatedUser extends AuthenticatedUser_base {
|
|
16
|
+
}
|
|
17
|
+
declare const AuthenticatedUserWithProviderAccounts_base: RpcMiddleware.ServiceClass<AuthenticatedUserWithProviderAccounts, "@shivaedev/identity/AuthenticatedUserWithProviderAccounts", Identity | SessionUser | SessionUserWithProviderAccounts, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false>;
|
|
18
|
+
export declare class AuthenticatedUserWithProviderAccounts extends AuthenticatedUserWithProviderAccounts_base {
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;;AACzH,qBAAa,cAAe,SAAQ,mBAKK;CAAG;;AAC5C,qBAAa,aAAc,SAAQ,kBAOjC;CAAG;;AACL,qBAAa,kBAAmB,SAAQ,uBAK0E;CAAG;;AACrH,qBAAa,iBAAkB,SAAQ,sBAOrC;CAAG;;AACL,qBAAa,qCAAsC,SAAQ,0CAKzD;CAAG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { RpcMiddleware } from "effect/rpc";
|
|
3
|
+
import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
|
|
4
|
+
export class RequestTracing extends RpcMiddleware.Service()("@shivaedev/identity/RequestTracing") {
|
|
5
|
+
}
|
|
6
|
+
export class Authenticated extends RpcMiddleware.Service()("@shivaedev/identity/Authenticated", {
|
|
7
|
+
error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
|
|
8
|
+
}) {
|
|
9
|
+
}
|
|
10
|
+
export class MaybeAuthenticated extends RpcMiddleware.Service()("@shivaedev/identity/MaybeAuthenticated", { error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]) }) {
|
|
11
|
+
}
|
|
12
|
+
export class AuthenticatedUser extends RpcMiddleware.Service()("@shivaedev/identity/AuthenticatedUser", {
|
|
13
|
+
error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
|
|
14
|
+
}) {
|
|
15
|
+
}
|
|
16
|
+
export class AuthenticatedUserWithProviderAccounts extends RpcMiddleware.Service()("@shivaedev/identity/AuthenticatedUserWithProviderAccounts", {
|
|
17
|
+
error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
|
|
18
|
+
}) {
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAEzF,MAAM,OAAO,cAAe,SAAQ,aAAa,CAAC,OAAO,EAKtD,CAAC,oCAAoC,CAAC;CAAG;AAC5C,MAAM,OAAO,aAAc,SAAQ,aAAa,CAAC,OAAO,EAKrD,CAAC,mCAAmC,EAAE;IACxC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;CAC/D,CAAC;CAAG;AACL,MAAM,OAAO,kBAAmB,SAAQ,aAAa,CAAC,OAAO,EAK1D,CAAC,wCAAwC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;CAAG;AACrH,MAAM,OAAO,iBAAkB,SAAQ,aAAa,CAAC,OAAO,EAKzD,CAAC,uCAAuC,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;CAC/D,CAAC;CAAG;AACL,MAAM,OAAO,qCAAsC,SAAQ,aAAa,CAAC,OAAO,EAG7E,CAAC,2DAA2D,EAAE;IAChE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;CAC/D,CAAC;CAAG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { RpcMiddleware } from "effect/rpc";
|
|
3
|
+
import type { Permission } from "@shivaedev/access/permission.ts";
|
|
4
|
+
import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
|
|
5
|
+
import { type Identity, SessionUser, type SessionUserValue } from "./identity.ts";
|
|
6
|
+
export declare function permissionMiddleware<TSelf>(): <const TName extends string>(name: TName, permission: Permission) => RpcMiddleware.ServiceClass<TSelf, TName, Identity | SessionUser, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false> & {
|
|
7
|
+
permission: Permission;
|
|
8
|
+
};
|
|
9
|
+
export declare function hasPermission(user: Pick<SessionUserValue, "id" | "permissions">, permission: Permission): boolean;
|
|
10
|
+
export declare function requirePermission(permission: Permission): Effect.Effect<SessionUserValue, Forbidden, SessionUser>;
|
|
11
|
+
//# sourceMappingURL=permission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAAE,KAAK,QAAQ,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIlF,wBAAgB,oBAAoB,CAAC,KAAK,MACjC,KAAK,CAAC,KAAK,SAAS,MAAM,QAAQ,KAAK,cAAc,UAAU;;EAEvE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,aAAa,CAAC,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAEjH;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,2DAMvD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { RpcMiddleware } from "effect/rpc";
|
|
3
|
+
import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
|
|
4
|
+
import { SessionUser } from "./identity.js";
|
|
5
|
+
const Failures = Schema.Union([Unauthorized, AuthUnavailable, Forbidden]);
|
|
6
|
+
export function permissionMiddleware() {
|
|
7
|
+
return (name, permission) => Object.assign(RpcMiddleware.Service()(name, { error: Failures }), { permission });
|
|
8
|
+
}
|
|
9
|
+
export function hasPermission(user, permission) {
|
|
10
|
+
return user.permissions?.some((grant) => grant.name === permission.name && grant.strength === permission.strength) ?? false;
|
|
11
|
+
}
|
|
12
|
+
export function requirePermission(permission) {
|
|
13
|
+
return Effect.flatMap(SessionUser, (user) => hasPermission(user, permission)
|
|
14
|
+
? Effect.succeed(user)
|
|
15
|
+
: Effect.fail(new Forbidden({ message: `Permission required: ${permission.name} (${permission.strength})` })));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=permission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.js","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAAiB,WAAW,EAAyB,MAAM,eAAe,CAAC;AAElF,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC;AAE1E,MAAM,UAAU,oBAAoB;IACnC,OAAO,CAA6B,IAAW,EAAE,UAAsB,EAAE,EAAE,CAC1E,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAA+C,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;AACjI,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAkD,EAAE,UAAsB;IACvG,OAAO,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;AAC7H,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAsB;IACvD,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3C,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC;QAC9B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,wBAAwB,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAC9G,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { AuthUnavailable, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
|
|
3
|
+
import type { ProviderAccountValue } from "#identity.ts";
|
|
4
|
+
import type { SessionProvider, SessionShape } from "#server/session.ts";
|
|
5
|
+
export type GetSession<TSession extends SessionShape> = (headers: globalThis.Headers) => Promise<TSession | null>;
|
|
6
|
+
export type GetProviderAccounts = (headers: globalThis.Headers) => Promise<readonly ProviderAccountValue[]>;
|
|
7
|
+
export type SessionWithProviderAccounts<TSession extends SessionShape> = TSession & {
|
|
8
|
+
readonly user: TSession["user"] & {
|
|
9
|
+
readonly providerAccounts: Effect.Effect<readonly ProviderAccountValue[], AuthUnavailable | Unauthorized>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export declare function betterAuthSessions<TSession extends SessionShape>(getSession: GetSession<TSession>): SessionProvider<TSession>;
|
|
13
|
+
export declare function betterAuthSessions<TSession extends SessionShape>(getSession: GetSession<TSession>, getProviderAccounts: GetProviderAccounts): SessionProvider<SessionWithProviderAccounts<TSession>>;
|
|
14
|
+
//# sourceMappingURL=betterAuthSessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"betterAuthSessions.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAC;AAGnD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,MAAM,MAAM,UAAU,CAAC,QAAQ,SAAS,YAAY,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAClH,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,KAAK,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAAC;AAC5G,MAAM,MAAM,2BAA2B,CAAC,QAAQ,SAAS,YAAY,IAAI,QAAQ,GAAG;IACnF,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG;QAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,oBAAoB,EAAE,EAAE,eAAe,GAAG,YAAY,CAAC,CAAA;KAAE,CAAC;CAChJ,CAAC;AAOF,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAAE,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;AAC/H,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAC/D,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,EAChC,mBAAmB,EAAE,mBAAmB,GACtC,eAAe,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Effect, Option, Predicate } from "effect";
|
|
2
|
+
import { redact } from "@shivaedev/errors/redact.ts";
|
|
3
|
+
import { AuthUnavailable, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
|
|
4
|
+
function unavailable(cause) {
|
|
5
|
+
return Effect.andThen(Effect.logError("Authentication provider failed", redact(cause)), Effect.fail(new AuthUnavailable({ message: "Authentication is temporarily unavailable" })));
|
|
6
|
+
}
|
|
7
|
+
export function betterAuthSessions(getSession, getProviderAccounts) {
|
|
8
|
+
const betterAuthSession = Effect.fn("PlatformRpc.betterAuthSession")(function* (headers) {
|
|
9
|
+
const transport = new globalThis.Headers(headers);
|
|
10
|
+
const session = yield* Effect.tryPromise(() => getSession(transport)).pipe(Effect.catch((error) => unavailable(error.cause)));
|
|
11
|
+
if (session === null || getProviderAccounts === undefined) {
|
|
12
|
+
return Option.fromNullishOr(session);
|
|
13
|
+
}
|
|
14
|
+
const providerAccounts = Effect.tryPromise({
|
|
15
|
+
catch: (cause) => cause,
|
|
16
|
+
try: () => getProviderAccounts(transport),
|
|
17
|
+
}).pipe(Effect.catch((cause) => Predicate.hasProperty(cause, "statusCode") && cause.statusCode === 401
|
|
18
|
+
? Effect.fail(new Unauthorized({ message: "Authentication required" }))
|
|
19
|
+
: unavailable(cause)));
|
|
20
|
+
return Option.some({ ...session, user: { ...session.user, providerAccounts } });
|
|
21
|
+
});
|
|
22
|
+
return { get: betterAuthSession };
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=betterAuthSessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"betterAuthSessions.js","sourceRoot":"","sources":["../../../src/server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnD,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAQ9E,SAAS,WAAW,CAAC,KAAc;IAClC,OAAO,MAAM,CAAC,OAAO,CACpB,MAAM,CAAC,QAAQ,CAAC,gCAAgC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAChE,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,2CAA2C,EAAE,CAAC,CAAC,CAC1F,CAAC;AACH,CAAC;AAMD,MAAM,UAAU,kBAAkB,CAAgC,UAAgC,EAAE,mBAAyC;IAC5I,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,+BAA+B,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAwB;QACvG,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9H,IAAI,OAAO,KAAK,IAAI,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;YAC3D,OAAO,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC;YAC1C,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;YACvB,GAAG,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC;SACzC,CAAC,CAAC,IAAI,CACN,MAAM,CAAC,KAAK,CACX,CAAC,KAAK,EAAwD,EAAE,CAC/D,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG;YACrE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;YACvE,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CACtB,CACD,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Config, Schema } from "effect";
|
|
2
|
+
export declare const AllowedAccounts: Schema.decodeTo<Schema.$Array<Schema.decodeTo<Schema.Struct<{
|
|
3
|
+
readonly accountId: Schema.NonEmptyString;
|
|
4
|
+
readonly providerId: Schema.NonEmptyString;
|
|
5
|
+
}>, Schema.String, never, never>>, Schema.String, never, never>;
|
|
6
|
+
export declare const allowedAccounts: Config.Config<readonly {
|
|
7
|
+
readonly accountId: string;
|
|
8
|
+
readonly providerId: string;
|
|
9
|
+
}[]>;
|
|
10
|
+
//# sourceMappingURL=allowedAccounts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allowedAccounts.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/allowedAccounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAgBtD,eAAO,MAAM,eAAe;;;+DAU3B,CAAC;AAEF,eAAO,MAAM,eAAe;;;IAA0D,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Config, Schema, SchemaGetter } from "effect";
|
|
2
|
+
const ProviderAccount = Schema.Struct({ accountId: Schema.NonEmptyString, providerId: Schema.NonEmptyString });
|
|
3
|
+
const AccountEntry = Schema.String.pipe(Schema.decodeTo(ProviderAccount, {
|
|
4
|
+
decode: SchemaGetter.transform((entry) => {
|
|
5
|
+
const separator = entry.indexOf(":");
|
|
6
|
+
return separator < 0
|
|
7
|
+
? { accountId: "", providerId: entry }
|
|
8
|
+
: { accountId: entry.slice(separator + 1).trim(), providerId: entry.slice(0, separator).trim() };
|
|
9
|
+
}),
|
|
10
|
+
encode: SchemaGetter.transform(({ accountId, providerId }) => `${providerId}:${accountId}`),
|
|
11
|
+
}));
|
|
12
|
+
export const AllowedAccounts = Schema.String.pipe(Schema.decodeTo(Schema.Array(AccountEntry).check(Schema.isMinLength(1)), {
|
|
13
|
+
decode: SchemaGetter.transform((value) => value
|
|
14
|
+
.split(",")
|
|
15
|
+
.map((entry) => entry.trim())
|
|
16
|
+
.filter((entry) => entry.length > 0)),
|
|
17
|
+
encode: SchemaGetter.transform((entries) => entries.join(",")),
|
|
18
|
+
}));
|
|
19
|
+
export const allowedAccounts = Config.schema(AllowedAccounts, "AUTH_ALLOWED_ACCOUNTS");
|
|
20
|
+
//# sourceMappingURL=allowedAccounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allowedAccounts.js","sourceRoot":"","sources":["../../../src/server/better-auth/allowedAccounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtD,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,cAAc,EAAE,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;AAE/G,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CACtC,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE;IAChC,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QACxC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,SAAS,GAAG,CAAC;YACnB,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE;YACtC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IACnG,CAAC,CAAC;IACF,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU,IAAI,SAAS,EAAE,CAAC;CAC3F,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAChD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;IACxE,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CACxC,KAAK;SACH,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CACrC;IACD,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;CAC9D,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BetterAuthOptions } from "better-auth";
|
|
2
|
+
export interface BearerSessionsOptions {
|
|
3
|
+
readonly origins: readonly string[];
|
|
4
|
+
}
|
|
5
|
+
export declare function withBearerSessions<TOptions extends BetterAuthOptions>(options: TOptions, enabled: boolean): TOptions;
|
|
6
|
+
export declare function hasSessionCookie(headers: Headers, cookieName: string): boolean;
|
|
7
|
+
export declare function sessionHeaders(headers: Headers, cookieName: string): Headers;
|
|
8
|
+
export declare function cookieSessionResponse(response: Response): Promise<Response>;
|
|
9
|
+
//# sourceMappingURL=bearerSessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bearerSessions.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/bearerSessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,iBAAiB,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,CAEpH;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAO9E;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAQ5E;AAED,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmBjF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { bearer } from "better-auth/plugins/bearer";
|
|
2
|
+
export function withBearerSessions(options, enabled) {
|
|
3
|
+
return enabled ? { ...options, plugins: [...(options.plugins ?? []), bearer({ requireSignature: true })] } : options;
|
|
4
|
+
}
|
|
5
|
+
export function hasSessionCookie(headers, cookieName) {
|
|
6
|
+
return (headers
|
|
7
|
+
.get("cookie")
|
|
8
|
+
?.split(";")
|
|
9
|
+
.some((cookie) => cookie.trim().startsWith(`${cookieName}=`)) === true);
|
|
10
|
+
}
|
|
11
|
+
export function sessionHeaders(headers, cookieName) {
|
|
12
|
+
const result = new Headers(headers);
|
|
13
|
+
if (hasSessionCookie(headers, cookieName)) {
|
|
14
|
+
result.delete("authorization");
|
|
15
|
+
}
|
|
16
|
+
else if (/^bearer\s/iu.test(headers.get("authorization") ?? "")) {
|
|
17
|
+
result.delete("cookie");
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
export async function cookieSessionResponse(response) {
|
|
22
|
+
const headers = new Headers(response.headers);
|
|
23
|
+
headers.delete("set-auth-token");
|
|
24
|
+
const exposed = headers.get("access-control-expose-headers");
|
|
25
|
+
if (exposed !== null) {
|
|
26
|
+
headers.set("access-control-expose-headers", exposed
|
|
27
|
+
.split(",")
|
|
28
|
+
.filter((header) => header.trim().toLowerCase() !== "set-auth-token")
|
|
29
|
+
.join(","));
|
|
30
|
+
}
|
|
31
|
+
if (!headers.get("content-type")?.includes("application/json")) {
|
|
32
|
+
return new Response(response.body, { headers, status: response.status });
|
|
33
|
+
}
|
|
34
|
+
const body = JSON.parse(await response.text(), (key, value) => (key === "token" ? undefined : value));
|
|
35
|
+
headers.delete("content-length");
|
|
36
|
+
return Response.json(body, { headers, status: response.status });
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=bearerSessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bearerSessions.js","sourceRoot":"","sources":["../../../src/server/better-auth/bearerSessions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAMpD,MAAM,UAAU,kBAAkB,CAAqC,OAAiB,EAAE,OAAgB;IACzG,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AACtH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB,EAAE,UAAkB;IACpE,OAAO,CACN,OAAO;SACL,GAAG,CAAC,QAAQ,CAAC;QACd,EAAE,KAAK,CAAC,GAAG,CAAC;SACX,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC,KAAK,IAAI,CACvE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB,EAAE,UAAkB;IAClE,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAChC,CAAC;SAAM,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACnE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,QAAkB;IAC7D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC7D,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CACV,+BAA+B,EAC/B,OAAO;aACL,KAAK,CAAC,GAAG,CAAC;aACV,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,gBAAgB,CAAC;aACpE,IAAI,CAAC,GAAG,CAAC,CACX,CAAC;IACH,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,KAAc,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACxH,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HttpServerRequest } from "effect/http";
|
|
2
|
+
export declare const PEER_IP_HEADER = "x-platform-client-ip";
|
|
3
|
+
export declare function clientIpHeaders(options: {
|
|
4
|
+
readonly clientIpHeader: string;
|
|
5
|
+
readonly ipv6Subnet?: number | undefined;
|
|
6
|
+
readonly trustedProxy?: string | undefined;
|
|
7
|
+
}): (request: HttpServerRequest.HttpServerRequest, web: Request) => void;
|
|
8
|
+
//# sourceMappingURL=clientIp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientIp.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/clientIp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACxC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C,aASiB,iBAAiB,CAAC,iBAAiB,OAAO,OAAO,UAalE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getIP } from "better-auth/api";
|
|
2
|
+
import { Option } from "effect";
|
|
3
|
+
import { trustedProxyPeer, trustedProxyRanges } from "#server/local.ts";
|
|
4
|
+
export const PEER_IP_HEADER = "x-platform-client-ip";
|
|
5
|
+
export function clientIpHeaders(options) {
|
|
6
|
+
const trustedPeer = trustedProxyPeer(options.trustedProxy);
|
|
7
|
+
const advanced = {
|
|
8
|
+
ipAddress: {
|
|
9
|
+
ipAddressHeaders: [options.clientIpHeader],
|
|
10
|
+
...(options.ipv6Subnet === undefined ? {} : { ipv6Subnet: options.ipv6Subnet }),
|
|
11
|
+
trustedProxies: trustedProxyRanges(options.trustedProxy),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
return (request, web) => {
|
|
15
|
+
web.headers.delete(PEER_IP_HEADER);
|
|
16
|
+
const trusted = Option.exists(request.remoteAddress, trustedPeer);
|
|
17
|
+
const forwardedIp = trusted ? getIP(web, { advanced }) : null;
|
|
18
|
+
if (!trusted) {
|
|
19
|
+
web.headers.delete("x-forwarded-for");
|
|
20
|
+
web.headers.delete(options.clientIpHeader);
|
|
21
|
+
}
|
|
22
|
+
const address = forwardedIp ?? Option.getOrUndefined(request.remoteAddress);
|
|
23
|
+
if (address !== undefined) {
|
|
24
|
+
web.headers.set(PEER_IP_HEADER, address);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=clientIp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientIp.js","sourceRoot":"","sources":["../../../src/server/better-auth/clientIp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAExE,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAErD,MAAM,UAAU,eAAe,CAAC,OAI/B;IACA,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG;QAChB,SAAS,EAAE;YACV,gBAAgB,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC;YAC1C,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;YAC/E,cAAc,EAAE,kBAAkB,CAAC,OAAO,CAAC,YAAY,CAAC;SACxD;KACD,CAAC;IACF,OAAO,CAAC,OAA4C,EAAE,GAAY,EAAE,EAAE;QACrE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;QAClE,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;YACtC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,IAAI,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC5E,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoryRateLimit.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/memoryRateLimit.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AAUvC,eAAO,MAAM,eAAe,sGA4C1B,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Clock, Effect } from "effect";
|
|
2
|
+
const MAX_ENTRIES = 100_000;
|
|
3
|
+
export const memoryRateLimit = Effect.gen(function* () {
|
|
4
|
+
const clock = yield* Clock.Clock;
|
|
5
|
+
const buckets = yield* Effect.acquireRelease(Effect.sync(() => new Map()), (entries) => Effect.sync(() => entries.clear()));
|
|
6
|
+
let nextExpiry = Number.POSITIVE_INFINITY;
|
|
7
|
+
function prune(now) {
|
|
8
|
+
if (now >= nextExpiry) {
|
|
9
|
+
nextExpiry = Number.POSITIVE_INFINITY;
|
|
10
|
+
for (const [entryKey, entry] of buckets) {
|
|
11
|
+
if (now >= entry.expiresAt) {
|
|
12
|
+
buckets.delete(entryKey);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
nextExpiry = Math.min(nextExpiry, entry.expiresAt);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const storage = {
|
|
21
|
+
consume(key, rule) {
|
|
22
|
+
const now = clock.currentTimeMillisUnsafe();
|
|
23
|
+
prune(now);
|
|
24
|
+
const bucket = buckets.get(key);
|
|
25
|
+
const window = rule.window * 1000;
|
|
26
|
+
if (bucket !== undefined && now - bucket.lastRequest < window && bucket.count >= rule.max) {
|
|
27
|
+
return Promise.resolve({ allowed: false, retryAfter: Math.ceil((bucket.lastRequest + window - now) / 1000) });
|
|
28
|
+
}
|
|
29
|
+
nextExpiry = Math.min(nextExpiry, now + window);
|
|
30
|
+
buckets.set(key, {
|
|
31
|
+
count: bucket === undefined || now - bucket.lastRequest >= window ? 1 : bucket.count + 1,
|
|
32
|
+
expiresAt: now + window,
|
|
33
|
+
lastRequest: now,
|
|
34
|
+
});
|
|
35
|
+
if (buckets.size > MAX_ENTRIES) {
|
|
36
|
+
for (const oldest of buckets.keys()) {
|
|
37
|
+
buckets.delete(oldest);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return Promise.resolve({ allowed: true, retryAfter: null });
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
return storage;
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=memoryRateLimit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoryRateLimit.js","sourceRoot":"","sources":["../../../src/server/better-auth/memoryRateLimit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAQvC,MAAM,WAAW,GAAG,OAAO,CAAC;AAE5B,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAC3C,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,EAAkB,CAAC,EAC5C,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAC/C,CAAC;IACF,IAAI,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC1C,SAAS,KAAK,CAAC,GAAW;QACzB,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;YACvB,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC;YACtC,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;gBACzC,IAAI,GAAG,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACP,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;gBACpD,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IACD,MAAM,OAAO,GAA6D;QACzE,OAAO,CAAC,GAAG,EAAE,IAAI;YAChB,MAAM,GAAG,GAAG,KAAK,CAAC,uBAAuB,EAAE,CAAC;YAC5C,KAAK,CAAC,GAAG,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YAClC,IAAI,MAAM,KAAK,SAAS,IAAI,GAAG,GAAG,MAAM,CAAC,WAAW,GAAG,MAAM,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC3F,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YAC/G,CAAC;YACD,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,GAAG,MAAM,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;gBAChB,KAAK,EAAE,MAAM,KAAK,SAAS,IAAI,GAAG,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC;gBACxF,SAAS,EAAE,GAAG,GAAG,MAAM;gBACvB,WAAW,EAAE,GAAG;aAChB,CAAC,CAAC;YACH,IAAI,OAAO,CAAC,IAAI,GAAG,WAAW,EAAE,CAAC;gBAChC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;oBACrC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBACvB,MAAM;gBACP,CAAC;YACF,CAAC;YACD,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;KACD,CAAC;IACF,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC,CAAC"}
|