mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
refactor(api): 🎨 Move createLocalUser to a static method of User
This commit is contained in:
parent
9d70778abd
commit
9e9998ea82
3
cli.ts
3
cli.ts
|
|
@ -13,7 +13,6 @@ import extract from "extract-zip";
|
|||
import { MediaBackend } from "media-manager";
|
||||
import { lookup } from "mime-types";
|
||||
import { getUrl } from "~database/entities/Attachment";
|
||||
import { type UserType, createNewLocalUser } from "~database/entities/User";
|
||||
import { client, db } from "~drizzle/db";
|
||||
import { Emojis, Notes, OpenIdAccounts, Users } from "~drizzle/schema";
|
||||
import { Note } from "~packages/database-interface/note";
|
||||
|
|
@ -129,7 +128,7 @@ const cliBuilder = new CliBuilder([
|
|||
}
|
||||
|
||||
// Create user
|
||||
const newUser = await createNewLocalUser({
|
||||
const newUser = await User.fromDataLocal({
|
||||
email: email,
|
||||
password: password,
|
||||
username: username,
|
||||
|
|
|
|||
|
|
@ -379,69 +379,6 @@ export const resolveWebFinger = async (
|
|||
return User.resolve(relevantLink.href);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetches the list of followers associated with the actor and updates the user's followers
|
||||
*/
|
||||
export const fetchFollowers = () => {
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new LOCAL user.
|
||||
* @param data The data for the new user.
|
||||
* @returns The newly created user.
|
||||
*/
|
||||
export const createNewLocalUser = async (data: {
|
||||
username: string;
|
||||
display_name?: string;
|
||||
password: string;
|
||||
email: string;
|
||||
bio?: string;
|
||||
avatar?: string;
|
||||
header?: string;
|
||||
admin?: boolean;
|
||||
skipPasswordHash?: boolean;
|
||||
}): Promise<User | null> => {
|
||||
const keys = await generateUserKeys();
|
||||
|
||||
const newUser = (
|
||||
await db
|
||||
.insert(Users)
|
||||
.values({
|
||||
username: data.username,
|
||||
displayName: data.display_name ?? data.username,
|
||||
password: data.skipPasswordHash
|
||||
? data.password
|
||||
: await Bun.password.hash(data.password),
|
||||
email: data.email,
|
||||
note: data.bio ?? "",
|
||||
avatar: data.avatar ?? config.defaults.avatar,
|
||||
header: data.header ?? config.defaults.avatar,
|
||||
isAdmin: data.admin ?? false,
|
||||
publicKey: keys.public_key,
|
||||
privateKey: keys.private_key,
|
||||
updatedAt: new Date().toISOString(),
|
||||
source: {
|
||||
language: null,
|
||||
note: "",
|
||||
privacy: "public",
|
||||
sensitive: false,
|
||||
fields: [],
|
||||
},
|
||||
})
|
||||
.returning()
|
||||
)[0];
|
||||
|
||||
const finalUser = await User.fromId(newUser.id);
|
||||
|
||||
if (!finalUser) return null;
|
||||
|
||||
// Add to Meilisearch
|
||||
await addUserToMeilisearch(finalUser);
|
||||
|
||||
return finalUser;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses mentions from a list of URIs
|
||||
*/
|
||||
|
|
@ -537,31 +474,6 @@ export const getRelationshipToOtherUser = async (
|
|||
return foundRelationship;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates keys for the user.
|
||||
*/
|
||||
export const generateUserKeys = async () => {
|
||||
const keys = await crypto.subtle.generateKey("Ed25519", true, [
|
||||
"sign",
|
||||
"verify",
|
||||
]);
|
||||
|
||||
const privateKey = Buffer.from(
|
||||
await crypto.subtle.exportKey("pkcs8", keys.privateKey),
|
||||
).toString("base64");
|
||||
|
||||
const publicKey = Buffer.from(
|
||||
await crypto.subtle.exportKey("spki", keys.publicKey),
|
||||
).toString("base64");
|
||||
|
||||
// Add header, footer and newlines later on
|
||||
// These keys are base64 encrypted
|
||||
return {
|
||||
private_key: privateKey,
|
||||
public_key: publicKey,
|
||||
};
|
||||
};
|
||||
|
||||
export const followRequestToLysand = (
|
||||
follower: User,
|
||||
followee: User,
|
||||
|
|
|
|||
|
|
@ -262,6 +262,79 @@ export class User {
|
|||
return this.user.avatar;
|
||||
}
|
||||
|
||||
static async generateKeys() {
|
||||
const keys = await crypto.subtle.generateKey("Ed25519", true, [
|
||||
"sign",
|
||||
"verify",
|
||||
]);
|
||||
|
||||
const privateKey = Buffer.from(
|
||||
await crypto.subtle.exportKey("pkcs8", keys.privateKey),
|
||||
).toString("base64");
|
||||
|
||||
const publicKey = Buffer.from(
|
||||
await crypto.subtle.exportKey("spki", keys.publicKey),
|
||||
).toString("base64");
|
||||
|
||||
// Add header, footer and newlines later on
|
||||
// These keys are base64 encrypted
|
||||
return {
|
||||
private_key: privateKey,
|
||||
public_key: publicKey,
|
||||
};
|
||||
}
|
||||
|
||||
static async fromDataLocal(data: {
|
||||
username: string;
|
||||
display_name?: string;
|
||||
password: string;
|
||||
email: string;
|
||||
bio?: string;
|
||||
avatar?: string;
|
||||
header?: string;
|
||||
admin?: boolean;
|
||||
skipPasswordHash?: boolean;
|
||||
}): Promise<User | null> {
|
||||
const keys = await User.generateKeys();
|
||||
|
||||
const newUser = (
|
||||
await db
|
||||
.insert(Users)
|
||||
.values({
|
||||
username: data.username,
|
||||
displayName: data.display_name ?? data.username,
|
||||
password: data.skipPasswordHash
|
||||
? data.password
|
||||
: await Bun.password.hash(data.password),
|
||||
email: data.email,
|
||||
note: data.bio ?? "",
|
||||
avatar: data.avatar ?? config.defaults.avatar,
|
||||
header: data.header ?? config.defaults.avatar,
|
||||
isAdmin: data.admin ?? false,
|
||||
publicKey: keys.public_key,
|
||||
privateKey: keys.private_key,
|
||||
updatedAt: new Date().toISOString(),
|
||||
source: {
|
||||
language: null,
|
||||
note: "",
|
||||
privacy: "public",
|
||||
sensitive: false,
|
||||
fields: [],
|
||||
},
|
||||
})
|
||||
.returning()
|
||||
)[0];
|
||||
|
||||
const finalUser = await User.fromId(newUser.id);
|
||||
|
||||
if (!finalUser) return null;
|
||||
|
||||
// Add to Meilisearch
|
||||
await addUserToMeilisearch(finalUser);
|
||||
|
||||
return finalUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's header in raw URL format
|
||||
* @param config The config to use
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export const meta = applyConfig({
|
|||
route: "/api/v1/accounts/:id/followers",
|
||||
auth: {
|
||||
required: false,
|
||||
oauthPermissions: [],
|
||||
oauthPermissions: ["read:accounts"],
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -36,7 +36,6 @@ export default apiRoute<typeof meta, typeof schema>(
|
|||
return errorResponse("Invalid ID, must be of type UUIDv7", 404);
|
||||
}
|
||||
|
||||
// TODO: Add pinned
|
||||
const { max_id, min_id, since_id, limit } = extraData.parsedRequest;
|
||||
|
||||
const otherUser = await User.fromId(id);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export const meta = applyConfig({
|
|||
route: "/api/v1/accounts/:id/following",
|
||||
auth: {
|
||||
required: false,
|
||||
oauthPermissions: [],
|
||||
oauthPermissions: ["read:accounts"],
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -36,7 +36,6 @@ export default apiRoute<typeof meta, typeof schema>(
|
|||
return errorResponse("Invalid ID, must be of type UUIDv7", 404);
|
||||
}
|
||||
|
||||
// TODO: Add pinned
|
||||
const { max_id, min_id, since_id, limit } = extraData.parsedRequest;
|
||||
|
||||
const otherUser = await User.fromId(id);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { tempmailDomains } from "@tempmail";
|
|||
import { eq } from "drizzle-orm";
|
||||
import ISO6391 from "iso-639-1";
|
||||
import { z } from "zod";
|
||||
import { createNewLocalUser } from "~database/entities/User";
|
||||
import { Users } from "~drizzle/schema";
|
||||
import { User } from "~packages/database-interface/user";
|
||||
|
||||
|
|
@ -207,7 +206,7 @@ export default apiRoute<typeof meta, typeof schema>(
|
|||
);
|
||||
}
|
||||
|
||||
await createNewLocalUser({
|
||||
await User.fromDataLocal({
|
||||
username: body.username ?? "",
|
||||
password: body.password ?? "",
|
||||
email: body.email ?? "",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { randomBytes } from "node:crypto";
|
||||
import { asc, inArray, like } from "drizzle-orm";
|
||||
import type { Status } from "~database/entities/Status";
|
||||
import { createNewLocalUser } from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { Notes, Tokens, Users } from "~drizzle/schema";
|
||||
import { server } from "~index";
|
||||
import { Note } from "~packages/database-interface/note";
|
||||
import type { User } from "~packages/database-interface/user";
|
||||
import { User } from "~packages/database-interface/user";
|
||||
/**
|
||||
* This allows us to send a test request to the server even when it isnt running
|
||||
* CURRENTLY NOT WORKING, NEEDS TO BE FIXED
|
||||
|
|
@ -33,7 +32,7 @@ export const getTestUsers = async (count: number) => {
|
|||
for (let i = 0; i < count; i++) {
|
||||
const password = randomBytes(32).toString("hex");
|
||||
|
||||
const user = await createNewLocalUser({
|
||||
const user = await User.fromDataLocal({
|
||||
username: `test-${randomBytes(32).toString("hex")}`,
|
||||
email: `${randomBytes(32).toString("hex")}@test.com`,
|
||||
password,
|
||||
|
|
|
|||
Loading…
Reference in a new issue