@shivaedev/server 0.6.0 → 0.7.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/dist/appHost.d.ts +2 -2
- package/dist/hostChanges.d.ts +2 -2
- package/dist/hostChanges.d.ts.map +1 -1
- package/dist/hostChanges.js +5 -5
- package/dist/hostChanges.js.map +1 -1
- package/dist/socketRpc.d.ts.map +1 -1
- package/dist/socketRpc.js +3 -0
- package/dist/socketRpc.js.map +1 -1
- package/package.json +7 -8
- package/src/hostChanges.ts +9 -8
- package/src/socketRpc.ts +3 -0
package/dist/appHost.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ declare const AppChanges_base: Context.ServiceClass<AppChanges, "@shivaedev/serv
|
|
|
27
27
|
} | {
|
|
28
28
|
readonly _tag: "Resync";
|
|
29
29
|
}, never, never>;
|
|
30
|
-
subscribe: (subscription: import("@shivaedev/contract/querySubscription.ts").QuerySubscription, context?: import("@shivaedev/changes/keys.ts").KeyContext) => import("effect/Stream").Stream<{
|
|
30
|
+
subscribe: <E, R>(subscription: import("@shivaedev/contract/querySubscription.ts").QuerySubscription<E, R>, context?: import("@shivaedev/changes/keys.ts").KeyContext) => import("effect/Stream").Stream<{
|
|
31
31
|
readonly _tag: "Changed";
|
|
32
32
|
readonly keys: readonly ({
|
|
33
33
|
readonly _tag: "Bucket";
|
|
@@ -45,7 +45,7 @@ declare const AppChanges_base: Context.ServiceClass<AppChanges, "@shivaedev/serv
|
|
|
45
45
|
readonly queryIndexes?: readonly number[] | undefined;
|
|
46
46
|
} | {
|
|
47
47
|
readonly _tag: "Resync";
|
|
48
|
-
}, import("@shivaedev/contract/readPolicyErrors.ts").QueryReadDenied,
|
|
48
|
+
}, E | import("@shivaedev/contract/readPolicyErrors.ts").QueryReadDenied, R>;
|
|
49
49
|
}>;
|
|
50
50
|
export declare class AppChanges extends AppChanges_base {
|
|
51
51
|
}
|
package/dist/hostChanges.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Layer } from "effect";
|
|
2
2
|
import type { Rpc, RpcGroup } from "effect/rpc";
|
|
3
|
-
import {
|
|
4
|
-
import type { AppChanges } from "
|
|
3
|
+
import type { SessionPolicy, SessionShape } from "@shivaedev/identity/server/session.ts";
|
|
4
|
+
import type { AppChanges } from "#appHost.ts";
|
|
5
5
|
export declare function hostChanges<R extends Rpc.Any, TSession extends SessionShape>(group: RpcGroup.RpcGroup<R>, changesService: typeof AppChanges, sessions?: SessionPolicy<TSession>): Layer.Layer<Rpc.ToHandler<Extract<R, {
|
|
6
6
|
readonly _tag: `${string}.$changes`;
|
|
7
7
|
}>>, never, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hostChanges.d.ts","sourceRoot":"","sources":["../src/hostChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,EAAkB,MAAM,QAAQ,CAAC;AAEhE,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"hostChanges.d.ts","sourceRoot":"","sources":["../src/hostChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,EAAkB,MAAM,QAAQ,CAAC;AAEhE,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKhD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAGzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wBAAgB,WAAW,CAAC,CAAC,SAAS,GAAG,CAAC,GAAG,EAAE,QAAQ,SAAS,YAAY,EAC3E,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAC3B,cAAc,EAAE,OAAO,UAAU,EACjC,QAAQ,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC;mBAsCoC,GAAG,MAAM,WAAW;mBAG1F"}
|
package/dist/hostChanges.js
CHANGED
|
@@ -2,8 +2,9 @@ import { Context, Effect, Layer, Option, Stream } from "effect";
|
|
|
2
2
|
import { Headers } from "effect/http";
|
|
3
3
|
import { CurrentViewer } from "@shivaedev/contract/readPolicy.ts";
|
|
4
4
|
import { Unauthorized } from "@shivaedev/errors/taxonomy.ts";
|
|
5
|
-
import {
|
|
5
|
+
import { recheckSession } from "@shivaedev/identity/server/recheckSession.ts";
|
|
6
6
|
import { resolveChanges } from "@shivaedev/identity/server/sessionKeys.ts";
|
|
7
|
+
import { revalidateSession } from "@shivaedev/identity/server/socketSession.ts";
|
|
7
8
|
export function hostChanges(group, changesService, sessions) {
|
|
8
9
|
return Layer.effectContext(Effect.gen(function* () {
|
|
9
10
|
const changes = yield* Effect.serviceOption(changesService);
|
|
@@ -45,15 +46,14 @@ function authorizeSession(sessions, tag, viewer, policy) {
|
|
|
45
46
|
if (sessions === undefined) {
|
|
46
47
|
return policy;
|
|
47
48
|
}
|
|
48
|
-
return
|
|
49
|
+
return recheckSession(sessions, Headers.empty, tag).pipe(Effect.map((current) => Option.isNone(viewer) || (Option.isSome(current) && current.value.user.id === viewer.value.id)), Effect.catch(() => Effect.succeed(false)), Effect.flatMap((allowed) => (allowed ? policy : Effect.succeed(false))));
|
|
49
50
|
}
|
|
50
51
|
function sessionRevoked(sessions, tag, id) {
|
|
51
52
|
return Effect.gen(function* () {
|
|
52
|
-
yield*
|
|
53
|
-
const current = yield* resolveSession(sessions, Headers.empty, tag).pipe(Effect.catchTag("AuthUnavailable", () => Effect.succeed(undefined)));
|
|
53
|
+
const current = yield* recheckSession(sessions, Headers.empty, tag).pipe(Effect.catchTag("AuthUnavailable", () => Effect.succeed(undefined)));
|
|
54
54
|
if (current !== undefined && (Option.isNone(current) || current.value.user.id !== id)) {
|
|
55
55
|
return yield* new Unauthorized({ message: "Authentication required" });
|
|
56
56
|
}
|
|
57
|
-
}).pipe(
|
|
57
|
+
}).pipe((check) => revalidateSession(check, sessions.streamRevalidationInterval ?? "30 seconds"));
|
|
58
58
|
}
|
|
59
59
|
//# sourceMappingURL=hostChanges.js.map
|
package/dist/hostChanges.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hostChanges.js","sourceRoot":"","sources":["../src/hostChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAe,MAAM,mCAAmC,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"hostChanges.js","sourceRoot":"","sources":["../src/hostChanges.ts"],"names":[],"mappings":"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"}
|
package/dist/socketRpc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socketRpc.d.ts","sourceRoot":"","sources":["../src/socketRpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAW,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAG7E,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"socketRpc.d.ts","sourceRoot":"","sources":["../src/socketRpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAW,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAG7E,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAE1F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,wBAAgB,SAAS,CAAC,QAAQ,SAAS,YAAY,EACtD,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,KAAK,EAAE,iBAAiB,CAAC,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,EACvH,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,EAC5B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,aAAa,EAAE,SAAS,MAAM,EAAE,kHAmBhC"}
|
package/dist/socketRpc.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Headers, HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
|
3
3
|
import * as HttpStatus from "effect/http/HttpStatus";
|
|
4
4
|
import { localTransport } from "@shivaedev/identity/server/local.ts";
|
|
5
5
|
import { resolveSession } from "@shivaedev/identity/server/session.ts";
|
|
6
|
+
import { makeSocketSession, SocketSession } from "@shivaedev/identity/server/socketSession.ts";
|
|
6
7
|
export function socketRpc(handler, policy, trustedProxy, nativeOrigins) {
|
|
7
8
|
return Effect.gen(function* () {
|
|
8
9
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
@@ -11,6 +12,8 @@ export function socketRpc(handler, policy, trustedProxy, nativeOrigins) {
|
|
|
11
12
|
}
|
|
12
13
|
if (policy.policy !== "loopback") {
|
|
13
14
|
yield* resolveSession(policy.sessions, Headers.empty, "$connect");
|
|
15
|
+
const session = yield* makeSocketSession(policy.sessions.streamRevalidationInterval ?? "30 seconds");
|
|
16
|
+
return yield* Effect.provideService(handler, SocketSession, session);
|
|
14
17
|
}
|
|
15
18
|
return yield* handler;
|
|
16
19
|
}).pipe(Effect.catchTags({
|
package/dist/socketRpc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socketRpc.js","sourceRoot":"","sources":["../src/socketRpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAqB,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"socketRpc.js","sourceRoot":"","sources":["../src/socketRpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAqB,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAG/F,MAAM,UAAU,SAAS,CACxB,OAAuH,EACvH,MAA4B,EAC5B,YAAgC,EAChC,aAAgC;IAEhC,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;QAC3D,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3D,OAAO,kBAAkB,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACpH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAClC,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YAClE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,IAAI,YAAY,CAAC,CAAC;YACrG,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC;IACvB,CAAC,CAAC,CAAC,IAAI,CACN,MAAM,CAAC,SAAS,CAAC;QAChB,eAAe,EAAE,eAAe;QAChC,SAAS,EAAE,SAAS;KACpB,CAAC,CACF,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACvB,OAAO,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3G,CAAC;AACD,SAAS,SAAS;IACjB,OAAO,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AAClG,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "The Effect application host: HTTP and RPC serving, health, OTLP export, database and migrations, and development mode",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -48,19 +48,18 @@
|
|
|
48
48
|
"@shivaedev/contract": "0.22.0",
|
|
49
49
|
"@shivaedev/errors": "0.1.2",
|
|
50
50
|
"@shivaedev/http": "0.3.0",
|
|
51
|
-
"@shivaedev/identity": "0.
|
|
51
|
+
"@shivaedev/identity": "0.6.0",
|
|
52
52
|
"@shivaedev/local-postgres": "0.7.0",
|
|
53
|
-
"@shivaedev/sql": "0.26.
|
|
53
|
+
"@shivaedev/sql": "0.26.1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@effect/platform-node": "4.0.6",
|
|
57
57
|
"@effect/sql-pg": "4.0.6",
|
|
58
58
|
"@effect/vitest": "4.0.6",
|
|
59
|
-
"@shivaedev/jobs": "0.23.
|
|
60
|
-
"@shivaedev/quality": "0.
|
|
61
|
-
"@shivaedev/test": "0.
|
|
62
|
-
"@shivaedev/test-
|
|
63
|
-
"@shivaedev/test-story": "0.25.0",
|
|
59
|
+
"@shivaedev/jobs": "0.23.1",
|
|
60
|
+
"@shivaedev/quality": "0.47.0",
|
|
61
|
+
"@shivaedev/test-sql": "0.13.0",
|
|
62
|
+
"@shivaedev/test-story": "0.25.1",
|
|
64
63
|
"@types/node": "24.19.2",
|
|
65
64
|
"@types/pg": "8.20.0",
|
|
66
65
|
"better-auth": "1.7.12",
|
package/src/hostChanges.ts
CHANGED
|
@@ -4,9 +4,11 @@ import type { Rpc, RpcGroup } from "effect/rpc";
|
|
|
4
4
|
import { CurrentViewer, type Viewer } from "@shivaedev/contract/readPolicy.ts";
|
|
5
5
|
import type { QueryReference } from "@shivaedev/contract/serverMetadata.ts";
|
|
6
6
|
import { Unauthorized } from "@shivaedev/errors/taxonomy.ts";
|
|
7
|
-
import {
|
|
7
|
+
import { recheckSession } from "@shivaedev/identity/server/recheckSession.ts";
|
|
8
|
+
import type { SessionPolicy, SessionShape } from "@shivaedev/identity/server/session.ts";
|
|
8
9
|
import { resolveChanges } from "@shivaedev/identity/server/sessionKeys.ts";
|
|
9
|
-
import
|
|
10
|
+
import { revalidateSession } from "@shivaedev/identity/server/socketSession.ts";
|
|
11
|
+
import type { AppChanges } from "#appHost.ts";
|
|
10
12
|
|
|
11
13
|
export function hostChanges<R extends Rpc.Any, TSession extends SessionShape>(
|
|
12
14
|
group: RpcGroup.RpcGroup<R>,
|
|
@@ -54,16 +56,16 @@ export function hostChanges<R extends Rpc.Any, TSession extends SessionShape>(
|
|
|
54
56
|
);
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
function authorizeSession<TSession extends SessionShape>(
|
|
59
|
+
function authorizeSession<TSession extends SessionShape, E, R>(
|
|
58
60
|
sessions: SessionPolicy<TSession> | undefined,
|
|
59
61
|
tag: string,
|
|
60
62
|
viewer: Option.Option<Viewer>,
|
|
61
|
-
policy: Effect.Effect<boolean>,
|
|
63
|
+
policy: Effect.Effect<boolean, E, R>,
|
|
62
64
|
) {
|
|
63
65
|
if (sessions === undefined) {
|
|
64
66
|
return policy;
|
|
65
67
|
}
|
|
66
|
-
return
|
|
68
|
+
return recheckSession(sessions, Headers.empty, tag).pipe(
|
|
67
69
|
Effect.map((current) => Option.isNone(viewer) || (Option.isSome(current) && current.value.user.id === viewer.value.id)),
|
|
68
70
|
Effect.catch(() => Effect.succeed(false)),
|
|
69
71
|
Effect.flatMap((allowed) => (allowed ? policy : Effect.succeed(false))),
|
|
@@ -72,10 +74,9 @@ function authorizeSession<TSession extends SessionShape>(
|
|
|
72
74
|
|
|
73
75
|
function sessionRevoked<TSession extends SessionShape>(sessions: SessionPolicy<TSession>, tag: string, id: string) {
|
|
74
76
|
return Effect.gen(function* () {
|
|
75
|
-
yield*
|
|
76
|
-
const current = yield* resolveSession(sessions, Headers.empty, tag).pipe(Effect.catchTag("AuthUnavailable", () => Effect.succeed(undefined)));
|
|
77
|
+
const current = yield* recheckSession(sessions, Headers.empty, tag).pipe(Effect.catchTag("AuthUnavailable", () => Effect.succeed(undefined)));
|
|
77
78
|
if (current !== undefined && (Option.isNone(current) || current.value.user.id !== id)) {
|
|
78
79
|
return yield* new Unauthorized({ message: "Authentication required" });
|
|
79
80
|
}
|
|
80
|
-
}).pipe(
|
|
81
|
+
}).pipe((check) => revalidateSession(check, sessions.streamRevalidationInterval ?? "30 seconds"));
|
|
81
82
|
}
|
package/src/socketRpc.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Headers, HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
|
3
3
|
import * as HttpStatus from "effect/http/HttpStatus";
|
|
4
4
|
import { localTransport } from "@shivaedev/identity/server/local.ts";
|
|
5
5
|
import { resolveSession, type SessionShape } from "@shivaedev/identity/server/session.ts";
|
|
6
|
+
import { makeSocketSession, SocketSession } from "@shivaedev/identity/server/socketSession.ts";
|
|
6
7
|
import type { HostPolicy } from "#hostOptions.ts";
|
|
7
8
|
|
|
8
9
|
export function socketRpc<TSession extends SessionShape>(
|
|
@@ -18,6 +19,8 @@ export function socketRpc<TSession extends SessionShape>(
|
|
|
18
19
|
}
|
|
19
20
|
if (policy.policy !== "loopback") {
|
|
20
21
|
yield* resolveSession(policy.sessions, Headers.empty, "$connect");
|
|
22
|
+
const session = yield* makeSocketSession(policy.sessions.streamRevalidationInterval ?? "30 seconds");
|
|
23
|
+
return yield* Effect.provideService(handler, SocketSession, session);
|
|
21
24
|
}
|
|
22
25
|
return yield* handler;
|
|
23
26
|
}).pipe(
|