CI / test (push) Failing after 42s
People sign up on the website and link IMVU accounts by putting a code in the account's tagline, which the hub reads from IMVU's public API (the most recent proof wins; link caps per person). IMVU's age verification or Access Pass make an account adult. T5DE's proxy signs in with a device code and keeps a WebSocket open, reporting the IMVU account in use and the community products it wears; /online shows those who opted in. Moderators get a console: who's online, people, link caps, bans, roles, and the audit log. Tests run the website and API against an embedded Postgres and a fake IMVU API. Co-Authored-By: Claude Opus 5.5 <[email protected]>
79 lines
3.1 KiB
SQL
79 lines
3.1 KiB
SQL
-- Accounts (people), their linked IMVU accounts, website sessions, sign-ins from proxies, and the audit log.
|
|
|
|
create table persons (
|
|
id bigserial primary key,
|
|
username text not null,
|
|
password_hash text not null,
|
|
role text not null default 'user' check (role in ('user', 'moderator', 'admin')),
|
|
-- How many IMVU accounts the person may link; moderators raise it on request.
|
|
link_cap integer not null default 10 check (link_cap >= 0),
|
|
created_at timestamptz not null default now(),
|
|
banned_at timestamptz,
|
|
ban_reason text not null default ''
|
|
);
|
|
create unique index persons_username on persons (lower(username));
|
|
|
|
create table sessions (
|
|
token_hash bytea primary key,
|
|
person_id bigint not null references persons on delete cascade,
|
|
csrf text not null,
|
|
created_at timestamptz not null default now(),
|
|
expires_at timestamptz not null
|
|
);
|
|
create index sessions_person on sessions (person_id);
|
|
|
|
-- A linked IMVU account. Linking it again from another person moves it (the most recent proof wins).
|
|
create table imvu_links (
|
|
imvu_id bigint primary key,
|
|
person_id bigint not null references persons on delete cascade,
|
|
-- What catalogs and rooms see instead of the person, so a person's accounts can't be connected.
|
|
pairwise_id text not null unique,
|
|
username text not null,
|
|
linked_at timestamptz not null default now(),
|
|
age_verified boolean not null default false,
|
|
access_pass boolean not null default false,
|
|
checked_at timestamptz not null default now(),
|
|
show_badge boolean not null default false,
|
|
show_presence boolean not null default false
|
|
);
|
|
create index imvu_links_person on imvu_links (person_id);
|
|
|
|
-- A code the person is to put in an IMVU account's tagline, proving it's theirs.
|
|
create table link_challenges (
|
|
person_id bigint not null references persons on delete cascade,
|
|
imvu_id bigint not null,
|
|
username text not null,
|
|
code text not null,
|
|
created_at timestamptz not null default now(),
|
|
primary key (person_id, imvu_id)
|
|
);
|
|
|
|
-- Signing a proxy in: the proxy shows user_code, the person approves it on the website.
|
|
create table device_codes (
|
|
device_hash bytea primary key,
|
|
user_code text not null unique,
|
|
created_at timestamptz not null default now(),
|
|
expires_at timestamptz not null,
|
|
person_id bigint references persons on delete cascade,
|
|
consumed_at timestamptz
|
|
);
|
|
|
|
create table refresh_tokens (
|
|
token_hash bytea primary key,
|
|
person_id bigint not null references persons on delete cascade,
|
|
created_at timestamptz not null default now(),
|
|
last_used_at timestamptz not null default now(),
|
|
revoked_at timestamptz
|
|
);
|
|
create index refresh_tokens_person on refresh_tokens (person_id);
|
|
|
|
create table audit (
|
|
id bigserial primary key,
|
|
at timestamptz not null default now(),
|
|
actor_id bigint references persons on delete set null,
|
|
action text not null,
|
|
target text not null default '',
|
|
detail jsonb not null default '{}'
|
|
);
|
|
create index audit_at on audit (at desc);
|