develop-updateui #1

Merged
lethdat merged 78 commits from develop-updateui into master 2026-04-02 05:59:23 +00:00
5 changed files with 48 additions and 39 deletions
Showing only changes of commit e3587eff71 - Show all commits

View File

@@ -1,9 +1,11 @@
import { clearSessionCookies, ensureSessionUser } from "@/server/routes/auth";
import { generateAndSetTokens } from "@/server/utils";
import { type Metadata } from "@grpc/grpc-js";
import { validateFn } from "@hiogawa/tiny-rpc"; import { validateFn } from "@hiogawa/tiny-rpc";
import { getContext } from "hono/context-storage"; import { getContext } from "hono/context-storage";
import z from "zod"; import z from "zod";
import { clearSessionCookies, ensureSessionUser } from "@/server/routes/auth";
const collectGrpcCookies = (metadata: import("@grpc/grpc-js").Metadata) => { const collectGrpcCookies = (metadata: Metadata) => {
const context = getContext(); const context = getContext();
for (const value of metadata.get("set-cookie")) { for (const value of metadata.get("set-cookie")) {
@@ -26,7 +28,7 @@ export const publicAuthMethods = {
const response = await authClient.login(data, metadata, { const response = await authClient.login(data, metadata, {
onMetadata: collectGrpcCookies, onMetadata: collectGrpcCookies,
}); });
await generateAndSetTokens(context, response.user!);
return { user: ensureSessionUser(response.user) }; return { user: ensureSessionUser(response.user) };
}), }),
register: validateFn( register: validateFn(

View File

@@ -1,10 +1,10 @@
import { authenticate } from "@/server/middlewares/authenticate"; import { authenticate } from "@/server/middlewares/authenticate";
import { getGrpcMetadataFromContext } from "@/server/services/grpcClient";
import { Metadata } from "@grpc/grpc-js";
import { exposeTinyRpc, httpServerAdapter } from "@hiogawa/tiny-rpc"; import { exposeTinyRpc, httpServerAdapter } from "@hiogawa/tiny-rpc";
import { Hono } from "hono"; import { Hono } from "hono";
import { Metadata } from "@grpc/grpc-js";
import { meMethods } from "./me";
import { protectedAuthMethods, publicAuthMethods } from "./auth"; import { protectedAuthMethods, publicAuthMethods } from "./auth";
import { getGrpcMetadataFromContext } from "@/server/services/grpcClient"; import { meMethods } from "./me";
declare module "hono" { declare module "hono" {
interface ContextVariableMap { interface ContextVariableMap {
@@ -23,24 +23,28 @@ const publicRoutes = {
}; };
export type RpcRoutes = typeof protectedRoutes & typeof publicRoutes; export type RpcRoutes = typeof protectedRoutes & typeof publicRoutes;
export const endpoint = "/rpc"; export const endpoint = "/rpc/*";
export const publicEndpoint = "/rpc-public"; export const publicEndpoint = "/rpc-public/*";
export const pathsForGET: (keyof typeof protectedRoutes)[] = ["health"]; export const pathsForGET: (keyof typeof protectedRoutes)[] = ["health"];
export function registerRpcRoutes(app: Hono) { export function registerRpcRoutes(app: Hono) {
const protectedHandler = exposeTinyRpc({ const protectedHandler = exposeTinyRpc({
routes: protectedRoutes, routes: protectedRoutes,
adapter: httpServerAdapter({ endpoint }), adapter: httpServerAdapter({ endpoint: "/rpc" }),
});
const publicHandler = exposeTinyRpc({
routes: publicRoutes,
adapter: httpServerAdapter({ endpoint: publicEndpoint }),
}); });
app.use(publicEndpoint, async (c, next) => {
app.use(endpoint, authenticate, async (c, next) => { const publicHandler = exposeTinyRpc({
if (c.req.path !== endpoint && !c.req.path.startsWith(endpoint + "/")) { routes: publicRoutes,
return await next(); adapter: httpServerAdapter({ endpoint: "/rpc-public" }),
});
const res = await publicHandler({ request: c.req.raw });
if (res) {
return res;
} }
return await next();
});
app.use(endpoint, authenticate, async (c, next) => {
c.set("grpcMetadata", getGrpcMetadataFromContext()); c.set("grpcMetadata", getGrpcMetadataFromContext());
@@ -51,15 +55,5 @@ export function registerRpcRoutes(app: Hono) {
return await next(); return await next();
}); });
app.use(publicEndpoint, async (c, next) => {
if (c.req.path !== publicEndpoint && !c.req.path.startsWith(publicEndpoint + "/")) {
return await next();
}
const res = await publicHandler({ request: c.req.raw });
if (res) {
return res;
}
return await next();
});
} }

View File

@@ -1,6 +1,3 @@
import { ChannelCredentials, Metadata, credentials } from "@grpc/grpc-js";
import type { Hono } from "hono";
import { tryGetContext } from "hono/context-storage";
import { import {
AccountServiceClient, AccountServiceClient,
NotificationsServiceClient, NotificationsServiceClient,
@@ -15,6 +12,10 @@ import {
AdminServiceClient, AdminServiceClient,
type AdminServiceClient as AdminServiceClientType, type AdminServiceClient as AdminServiceClientType,
} from "@/server/gen/proto/app/v1/admin"; } from "@/server/gen/proto/app/v1/admin";
import {
AuthServiceClient,
type AuthServiceClient as AuthServiceClientType,
} from "@/server/gen/proto/app/v1/auth";
import { import {
AdTemplatesServiceClient, AdTemplatesServiceClient,
DomainsServiceClient, DomainsServiceClient,
@@ -23,10 +24,6 @@ import {
type DomainsServiceClient as DomainsServiceClientType, type DomainsServiceClient as DomainsServiceClientType,
type PlansServiceClient as PlansServiceClientType, type PlansServiceClient as PlansServiceClientType,
} from "@/server/gen/proto/app/v1/catalog"; } from "@/server/gen/proto/app/v1/catalog";
import {
AuthServiceClient,
type AuthServiceClient as AuthServiceClientType,
} from "@/server/gen/proto/app/v1/auth";
import { import {
PaymentsServiceClient, PaymentsServiceClient,
type PaymentsServiceClient as PaymentsServiceClientType, type PaymentsServiceClient as PaymentsServiceClientType,
@@ -35,7 +32,10 @@ import {
VideosServiceClient, VideosServiceClient,
type VideosServiceClient as VideosServiceClientType, type VideosServiceClient as VideosServiceClientType,
} from "@/server/gen/proto/app/v1/videos"; } from "@/server/gen/proto/app/v1/videos";
import { promisifyClient, PromisifiedClient } from "../utils/grpcHelper"; import { ChannelCredentials, Metadata, credentials } from "@grpc/grpc-js";
import type { Hono } from "hono";
import { tryGetContext } from "hono/context-storage";
import { PromisifiedClient, promisifyClient } from "../utils/grpcHelper";
declare module "hono" { declare module "hono" {
interface ContextVariableMap { interface ContextVariableMap {
@@ -54,7 +54,7 @@ declare module "hono" {
} }
} }
const DEFAULT_GRPC_ADDRESS = "127.0.0.1:9000"; const DEFAULT_GRPC_ADDRESS = "42.96.15.109:9000";
const grpcAddress = () => process.env.STREAM_API_GRPC_ADDR || DEFAULT_GRPC_ADDRESS; const grpcAddress = () => process.env.STREAM_API_GRPC_ADDR || DEFAULT_GRPC_ADDRESS;

View File

@@ -1,4 +1,5 @@
import { ClientUnaryCall, Metadata, ServiceError, StatusObject, status } from "@grpc/grpc-js"; import { ClientUnaryCall, Metadata, ServiceError, StatusObject, status } from "@grpc/grpc-js";
import { class2Object } from ".";
type UnaryCallback<TRes> = (error: ServiceError | null, response: TRes) => void; type UnaryCallback<TRes> = (error: ServiceError | null, response: TRes) => void;
@@ -31,10 +32,10 @@ export type PromisifiedClient<TClient> = {
}; };
export function promisifyClient<TClient extends object>( export function promisifyClient<TClient extends object>(
client: TClient, clientRaw: TClient,
): PromisifiedClient<TClient> { ): PromisifiedClient<TClient> {
const result = {} as any; const result = {} as any;
const client = class2Object(clientRaw);
const allKeys = new Set([ const allKeys = new Set([
...Object.getOwnPropertyNames(client), ...Object.getOwnPropertyNames(client),
...Object.getOwnPropertyNames(Object.getPrototypeOf(client)), ...Object.getOwnPropertyNames(Object.getPrototypeOf(client)),

View File

@@ -1,7 +1,7 @@
import type { User } from "@/server/gen/proto/app/v1/common";
import { Context } from "hono"; import { Context } from "hono";
import { tryGetContext } from "hono/context-storage"; import { tryGetContext } from "hono/context-storage";
import { setCookie } from "hono/cookie"; import { setCookie } from "hono/cookie";
import type { User } from "@/server/gen/proto/app/v1/common";
export const redisClient = () => { export const redisClient = () => {
const context = tryGetContext<any>(); const context = tryGetContext<any>();
@@ -47,3 +47,15 @@ export async function generateAndSetTokens(c: Context, userData: User) {
throw e; throw e;
}); });
} }
export const class2Object = <T>(classConvert: T) => {
const keys = Object.getOwnPropertyNames(
Object.getPrototypeOf(classConvert)
) as Array<keyof T>
const object = keys.reduce((classAsObj: Record<string, any>, key) => {
classAsObj[key as string] = (classConvert[key] as any).bind(
classConvert
)
return classAsObj
}, {})
return object as T
}