Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/takos_host/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export const authRequired: MiddlewareHandler = createAuthMiddleware({
await (session as unknown as { save: () => Promise<void> }).save();
},
attach: (c, session) => {
c.set("user", (session as unknown as { user: unknown }).user);
const id = String((session as unknown as { user: unknown }).user);
c.set("user", { _id: id });
},
});
36 changes: 17 additions & 19 deletions app/takos_host/consumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ import { z } from "zod";
import { zValidator } from "@hono/zod-validator";
import { authRequired, hash } from "./auth.ts";

import type { ObjectId } from "mongodb";

interface HostUserDoc {
_id: ObjectId;
userName: string;
email: string;
emailVerified: boolean;
_id: string;
userName?: string;
email?: string;
emailVerified?: boolean;
verifyCode?: string;
verifyCodeExpires?: Date;
hashedPassword: string;
salt: string;
createdAt: Date;
hashedPassword?: string;
salt?: string;
createdAt?: Date;
}
import { createDB } from "@takos_host/db";
import type { HostDataStore } from "./db/types.ts";
Expand All @@ -41,7 +39,7 @@ export function createConsumerApp(

app.get("/instances", async (c) => {
const user = c.get("user") as HostUserDoc;
const list = await db.host.listInstances(String(user._id));
const list = await db.host.listInstances(user._id);
return c.json(list);
});

Expand All @@ -56,7 +54,7 @@ export function createConsumerApp(
const host = rawHost.toLowerCase();
const user = c.get("user") as HostUserDoc;

if (await overLimit(String(user._id))) {
if (await overLimit(user._id)) {
return c.json({ error: "limit" }, 400);
}

Expand Down Expand Up @@ -114,7 +112,7 @@ export function createConsumerApp(
}
await db.host.createInstance({
host: fullHost,
owner: String(user._id),
owner: user._id,
env,
});
await db.tenant.ensure(fullHost, fullHost);
Expand All @@ -126,7 +124,7 @@ export function createConsumerApp(
app.delete("/instances/:host", async (c) => {
const host = c.req.param("host").toLowerCase();
const user = c.get("user") as HostUserDoc;
await db.host.deleteInstance(host, String(user._id));
await db.host.deleteInstance(host, user._id);
invalidate?.(host);
return c.json({ success: true });
});
Expand All @@ -136,7 +134,7 @@ export function createConsumerApp(
const user = c.get("user") as HostUserDoc;
const inst = await db.host.findInstanceByHostAndOwner(
host,
String(user._id),
user._id,
);
if (!inst) {
return c.json({ error: "not found" }, 404);
Expand All @@ -153,7 +151,7 @@ export function createConsumerApp(
const user = c.get("user") as HostUserDoc;
const inst = await db.host.findInstanceByHostAndOwner(
host,
String(user._id),
user._id,
);
if (!inst) return c.json({ error: "not found" }, 404);
if (password) {
Expand All @@ -177,7 +175,7 @@ export function createConsumerApp(
const user = c.get("user") as HostUserDoc;
const inst = await db.host.findInstanceByHostAndOwner(
host,
String(user._id),
user._id,
);
if (!inst) return c.json({ error: "not found" }, 404);
invalidate?.(host);
Expand Down Expand Up @@ -210,7 +208,7 @@ export function createConsumerApp(

app.get("/domains", async (c) => {
const user = c.get("user") as HostUserDoc;
const list = await db.domains.list(String(user._id));
const list = await db.domains.list(user._id);
return c.json(list);
});

Expand All @@ -223,15 +221,15 @@ export function createConsumerApp(
const exists = await db.domains.find(domain);
if (exists) return c.json({ error: "exists" }, 400);
const token = crypto.randomUUID();
await db.domains.create(domain, String(user._id), token);
await db.domains.create(domain, user._id, token);
return c.json({ success: true, token });
},
);

app.post("/domains/:domain/verify", async (c) => {
const domain = c.req.param("domain");
const user = c.get("user") as HostUserDoc;
const doc = await db.domains.find(domain, String(user._id));
const doc = await db.domains.find(domain, user._id);
if (!doc) return c.json({ error: "not found" }, 404);
try {
const res = await fetch(
Expand Down
31 changes: 20 additions & 11 deletions app/takos_host/db/mongo_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import Tenant from "../models/tenant.ts";
import Instance from "../models/instance.ts";
import OAuthClient from "../models/oauth_client.ts";
import HostDomain from "../models/domain.ts";
import type mongoose from "mongoose";
import mongoose from "mongoose";

const toObjectId = (id: string) => new mongoose.Types.ObjectId(id);

/**
* 既存の MongoDB 実装をホスト用 DataStore に束ねる実装。
Expand Down Expand Up @@ -135,11 +137,12 @@ export function createMongoDataStore(
},
host: {
listInstances: async (owner) => {
const docs = await Instance.find({ owner })
const docs = await Instance.find({ owner: toObjectId(owner) })
.lean<{ host: string }[]>();
return docs.map((d) => ({ host: d.host }));
},
countInstances: (owner) => Instance.countDocuments({ owner }),
countInstances: (owner) =>
Instance.countDocuments({ owner: toObjectId(owner) }),
findInstanceByHost: async (host) => {
const doc = await Instance.findOne({ host })
.lean<
Expand All @@ -160,7 +163,10 @@ export function createMongoDataStore(
: null;
},
findInstanceByHostAndOwner: async (host, owner) => {
const doc = await Instance.findOne({ host, owner })
const doc = await Instance.findOne({
host,
owner: toObjectId(owner),
})
.lean<
{
_id: mongoose.Types.ObjectId;
Expand All @@ -175,15 +181,16 @@ export function createMongoDataStore(
createInstance: async (data) => {
const doc = new Instance({
host: data.host,
owner: data.owner,
owner: toObjectId(data.owner),
env: data.env ?? {},
createdAt: new Date(),
});
await doc.save();
},
updateInstanceEnv: (id, env) =>
Instance.updateOne({ _id: id }, { $set: { env } }),
deleteInstance: (host, owner) => Instance.deleteOne({ host, owner }),
Instance.updateOne({ _id: toObjectId(id) }, { $set: { env } }),
deleteInstance: (host, owner) =>
Instance.deleteOne({ host, owner: toObjectId(owner) }),
},
oauth: {
list: async () => {
Expand Down Expand Up @@ -211,13 +218,13 @@ export function createMongoDataStore(
},
domains: {
list: async (user) => {
const docs = await HostDomain.find({ user })
const docs = await HostDomain.find({ user: toObjectId(user) })
.lean<{ domain: string; verified: boolean }[]>();
return docs.map((d) => ({ domain: d.domain, verified: d.verified }));
},
find: async (domain, user?) => {
const cond: Record<string, unknown> = { domain };
if (user) cond.user = user;
if (user) cond.user = toObjectId(user);
const doc = await HostDomain.findOne(cond)
.lean<
| { _id: mongoose.Types.ObjectId; token: string; verified: boolean }
Expand All @@ -230,15 +237,17 @@ export function createMongoDataStore(
create: async (domain, user, token) => {
const doc = new HostDomain({
domain,
user,
user: toObjectId(user),
token,
verified: false,
createdAt: new Date(),
});
await doc.save();
},
verify: (id) =>
HostDomain.updateOne({ _id: id }, { $set: { verified: true } }),
HostDomain.updateOne({ _id: toObjectId(id) }, {
$set: { verified: true },
}),
},
raw: () => impl.getDatabase(),
// 互換用: 旧 API で使用していた getDatabase を残す
Expand Down