feature: require invites

This commit is contained in:
Andy Burke 2025-10-08 14:42:01 -07:00
parent 8b70172493
commit a3302d2eff
22 changed files with 385 additions and 482 deletions

View file

@ -3,6 +3,8 @@ import { convert_to_words } from '@andyburke/lurid/word_bytes';
import { API_CLIENT } from '../utils/api.ts';
import { Cookie, getSetCookies } from '@std/http/cookie';
import { generateTotp } from '../utils/totp.ts';
import { USER } from '../models/user.ts';
import { SESSION } from '../models/session.ts';
const TLDs: string[] = [
'com',
@ -98,50 +100,74 @@ export async function get_ephemeral_listen_server(options?: SERVER_OPTIONS): Pro
return ephemeral_server;
}
type NEW_USER_INFO = {
username: string;
password: string;
export type TEST_USER_INFO = {
user: USER;
session: SESSION;
headers: Headers;
};
export async function get_new_user(client: API_CLIENT, user_info?: Record<string, any>): Promise<Record<string, any>> {
const info: Record<string, any> = {
export async function get_new_user(client: API_CLIENT, user_info?: Record<string, any>, inviting_user_info?: TEST_USER_INFO): Promise<TEST_USER_INFO> {
const new_user_request_json: Record<string, any> = {
username: random_username(),
password: `${random_username()} ! ${random_username()}`,
...user_info
};
if (
!((typeof new_user_request_json.password === 'string' && new_user_request_json.password.length) ||
(typeof new_user_request_json.password_hash === 'string' && new_user_request_json.password_hash.length))
) {
new_user_request_json.password = `${Math.round(Math.random() * 10)} - ${random_username()} ! ${random_username()}`;
}
if (inviting_user_info) {
const invite_code = await client.fetch(`/users/${inviting_user_info.user?.id}/invites`, {
method: 'POST',
headers: {
'x-session_id': inviting_user_info.session.id,
'x-totp': await generateTotp(inviting_user_info.session.secret)
},
json: {
code: random_username()
}
});
new_user_request_json.invite_code = invite_code.code;
}
await client.fetch('/users', {
method: 'POST',
json: info
json: new_user_request_json
});
const cookies: Cookie[] = [];
const auth_response: any = await client.fetch('/auth', {
method: 'POST',
json: info,
json: new_user_request_json,
done: (response) => {
cookies.push(...getSetCookies(response.headers));
}
});
info.user = auth_response.user;
info.session = auth_response.session;
const test_user_info: TEST_USER_INFO = {
user: auth_response.user,
session: auth_response.session,
headers: new Headers()
};
cookies.push({
name: 'totp',
value: await generateTotp(info.session?.secret),
value: await generateTotp(test_user_info.session?.secret),
maxAge: 30,
expires: Date.now() + 30_000,
path: '/'
});
info.headers_for_get = new Headers();
for (const cookie of cookies) {
info.headers_for_get.append(`x-${cookie.name}`, cookie.value);
test_user_info.headers.append(`x-${cookie.name}`, cookie.value);
}
info.headers_for_get.append('cookie', cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join('; '));
test_user_info.headers.append('cookie', cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join('; '));
return info;
return test_user_info;
}
export async function set_user_permissions(client: API_CLIENT, user: any, session: any, permissions: string[]): Promise<any> {
@ -157,3 +183,13 @@ export async function set_user_permissions(client: API_CLIENT, user: any, sessio
}
});
}
export async function delete_user(client: API_CLIENT, user_info: any): Promise<undefined> {
await client.fetch(`/users/${user_info.user.id}`, {
method: 'DELETE',
headers: {
'x-session_id': user_info.session.id,
'x-totp': await generateTotp(user_info.session.secret)
}
});
}