Initial commit.

This commit is contained in:
Andrew Pietila 2024-07-23 21:47:20 -05:00
parent 2cba568e5f
commit 05da3ed57c
10 changed files with 2119 additions and 17 deletions

2
.gitignore vendored
View file

@ -34,3 +34,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
brainz-social.db

7
db/drizzle.ts Normal file
View file

@ -0,0 +1,7 @@
import { drizzle } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';
const sqlite = new Database('brainz-social.db');
const db = drizzle(sqlite);
export default db;

10
drizzle.config.ts Normal file
View file

@ -0,0 +1,10 @@
import { defineConfig } from "drizzle-kit";
export default defineConfig({
dialect: "sqlite",
schema: "./src/schema.ts",
out: "./drizzle",
dbCredentials: {
"url": "./brainz-social.db"
}
})

View file

@ -0,0 +1,8 @@
CREATE TABLE `user` (
`id` integer PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`pwhash` text,
`activity` text
);
--> statement-breakpoint
CREATE UNIQUE INDEX `user_name_unique` ON `user` (`name`);

View file

@ -0,0 +1,62 @@
{
"version": "6",
"dialect": "sqlite",
"id": "cf30ee58-30df-4207-8eae-4fd88e71f6bb",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"user": {
"name": "user",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"pwhash": {
"name": "pwhash",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"activity": {
"name": "activity",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"user_name_unique": {
"name": "user_name_unique",
"columns": [
"name"
],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}

View file

@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "sqlite",
"entries": [
{
"idx": 0,
"version": "6",
"when": 1721619238248,
"tag": "0000_users_table",
"breakpoints": true
}
]
}

1960
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -9,18 +9,24 @@
"lint": "next lint"
},
"dependencies": {
"better-sqlite3": "^11.1.2",
"drizzle-orm": "^0.32.0",
"jsonld": "^8.3.2",
"next": "14.2.5",
"react": "^18",
"react-dom": "^18",
"next": "14.2.5"
"react-dom": "^18"
},
"devDependencies": {
"typescript": "^5",
"@types/better-sqlite3": "^7.6.11",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"drizzle-kit": "^0.23.0",
"eslint": "^8",
"eslint-config-next": "14.2.5",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"eslint": "^8",
"eslint-config-next": "14.2.5"
}
"typescript": "^5"
},
"packageManager": "npm@10.8.1"
}

View file

@ -0,0 +1,47 @@
import db from "../../../../db/drizzle";
import { NextRequest, NextResponse } from "next/server";
export const dynamic = 'force-dynamic';
export async function GET(request: NextRequest) {
const reqUrl = new URL(request.url);
console.log(reqUrl);
const reqResource = reqUrl.searchParams.get("resource");
// TODO: If this matches a URL, figure it out.
const matches = reqResource?.match(/acct:(.*)@(.*)/);
// if ( !matches || matches?.length === 0 ) {
// const res = new Response("", {status: 404});
// return res;
// }
// TODO: Multidomain
console.log(matches?.length);
if ( matches && matches.length === 3 && matches[2] === request.headers.get("host") ) {
// TODO: User specificity
return NextResponse.json({
"subject": `acct:${matches[1]}@${matches[2]}`,
"aliases": [`https://${matches[2]}/@${matches[1]}`, `https://${matches[2]}/users/${matches[1]}`],
"links": [{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": `https://${matches[2]}/@${matches[1]}`
}, {
"rel": "self",
"type": "application/activity+json",
"href": `https://${matches[2]}/users/${matches[1]}`
}, {
"rel": "http://ostatus.org/schema/1.0/subscribe",
"template": `https://${matches[2]}/authorize_interaction?uri={uri}`
}, {
"rel": "http://webfinger.net/rel/avatar",
"type": "image/png",
// TODO: Avatar URL.
"href": `https://files.${matches[2]}/avatar.png`
}]
}, {
headers: { "Content-Type": "application/jrd+json; charset=utf-8" }
})
}
const res = new Response("", {status: 404});
return res;
}

9
src/schema.ts Normal file
View file

@ -0,0 +1,9 @@
import { sql } from "drizzle-orm";
import { int, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
id: int("id").primaryKey(),
name: text("name").unique().notNull(),
pwHash: text("pwhash"),
activity: text("activity")
})