refactor(webapi)!: put all API under path /_blah

This commit is contained in:
oxalica 2024-09-19 04:56:57 -04:00
parent ab756f78ab
commit 0c28c00c3d
5 changed files with 34 additions and 28 deletions

View file

@ -129,7 +129,7 @@ impl AppState {
type ArcState = State<Arc<AppState>>;
pub fn router(st: Arc<AppState>) -> Router {
Router::new()
let router = Router::new()
.route("/ws", get(handle_ws))
.route("/user/me", get(user_get).post(user_register))
.route("/room", get(room_list))
@ -153,7 +153,8 @@ pub fn router(st: Arc<AppState>) -> Router {
HeaderName::from_static(X_BLAH_DIFFICULTY),
]),
)
.with_state(st)
.with_state(st);
Router::new().nest("/_blah", router)
}
type RE<T> = R<T, ApiError>;

View file

@ -95,8 +95,9 @@ fn socket_activate() {
}
let resp = rt.block_on(async {
let url = format!("http://127.0.0.1:{local_port}/_blah/room?filter=public");
let fut = async {
reqwest::get(format!("http://127.0.0.1:{local_port}/room?filter=public"))
reqwest::get(url)
.await
.unwrap()
.error_for_status()

View file

@ -130,7 +130,11 @@ struct Server {
impl Server {
fn url(&self, rhs: impl fmt::Display) -> String {
format!("http://{}:{}{}", LOCALHOST, self.port, rhs)
format!("{}/_blah{}", self.domain(), rhs)
}
fn domain(&self) -> String {
format!("http://{}:{}", LOCALHOST, self.port)
}
fn rng(&self) -> impl DerefMut<Target = impl RngCore> + use<'_> {
@ -881,7 +885,7 @@ async fn register(server: Server) {
register_fast(&req)
.await
.expect_api_err(StatusCode::BAD_REQUEST, "invalid_server_url");
req.server_url = server.url("").parse().unwrap();
req.server_url = server.domain().parse().unwrap();
register_fast(&req)
.await

View file

@ -6,7 +6,7 @@ info:
paths:
# OAPI does not support WebSocket interface definitions.
# See: https://github.com/OAI/OpenAPI-Specification/issues/55#issuecomment-929382279
/ws:
/_blah/ws:
get:
summary: WebSocket endpoint
description: |
@ -46,7 +46,7 @@ paths:
schema:
$ref: '#/components/schemas/WSServerToClient'
/user/me:
/_blah/user/me:
get:
summary: Check registration status of the current user
parameters:
@ -131,7 +131,7 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'
/room:
/_blah/room:
get:
summary: List rooms
parameters:
@ -190,7 +190,7 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'
/room/create:
/_blah/room/create:
post:
summary: Create a room
@ -238,7 +238,7 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'
/room/{rid}:
/_blah/room/{rid}:
get:
summary: Get room metadata
parameters:
@ -264,7 +264,7 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'
/room/{rid}/admin:
/_blah/room/{rid}/admin:
post:
summary: Room management
@ -295,7 +295,7 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'
/room/{rid}/feed.json:
/_blah/room/{rid}/feed.json:
get:
summary: Get JSON feed of room
description: |
@ -316,7 +316,7 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'
/room/{rid}/msg:
/_blah/room/{rid}/msg:
get:
summary: List messages in a room
description: |
@ -395,7 +395,7 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'
/room/{rid}/msg/{cid}/seen:
/_blah/room/{rid}/msg/{cid}/seen:
post:
summary: Mark a message seen
description: |

View file

@ -6,7 +6,7 @@ const roomsInput = document.querySelector('#rooms');
const joinNewRoomInput = document.querySelector('#join-new-room');
const chatInput = document.querySelector('#chat');
let serverUrl = null;
let apiUrl = null;
let curRoom = null;
let ws = null;
let keypair = null;
@ -117,19 +117,19 @@ async function register() {
const idUrl = prompt('id_url:', defaultConfig.id_url || '');
if (idUrl === null) return;
const getResp = await fetch(`${serverUrl}/user/me`, {
const getResp = await fetch(`${apiUrl}/user/me`, {
cache: 'no-store'
})
console.log(getResp.headers);
const challenge = getResp.headers.get('x-blah-nonce');
if (challenge === null) throw new Error('cannot get challenge nonce');
const postResp = await signAndPost(`${serverUrl}/user/me`, {
const postResp = await signAndPost(`${apiUrl}/user/me`, {
// sorted fields.
challenge_nonce: parseInt(challenge),
id_key: getIdPubkey(),
id_url: norm(idUrl),
server_url: norm(serverUrl),
server_url: norm(apiUrl),
typ: 'user_register',
})
if (!postResp.ok) throw new Error(`status ${getResp.status}: ${(await getResp.json()).error.message}`);
@ -219,7 +219,7 @@ async function enterRoom(rid) {
roomsInput.value = rid;
genAuthHeader()
.then(opts => fetch(`${serverUrl}/room/${rid}`, opts))
.then(opts => fetch(`${apiUrl}/room/${rid}`, opts))
.then(async (resp) => [resp.status, await resp.json()])
.then(async ([status, json]) => {
if (status !== 200) throw new Error(`status ${status}: ${json.error.message}`);
@ -230,7 +230,7 @@ async function enterRoom(rid) {
});
genAuthHeader()
.then(opts => fetch(`${serverUrl}/room/${rid}/msg`, opts))
.then(opts => fetch(`${apiUrl}/room/${rid}/msg`, opts))
.then(async (resp) => { return [resp.status, await resp.json()]; })
.then(async ([status, json]) => {
if (status !== 200) throw new Error(`status ${status}: ${json.error.message}`);
@ -256,7 +256,7 @@ async function connectServer(newServerUrl) {
log(`invalid url: ${e}`);
return;
}
serverUrl = newServerUrl;
apiUrl = wsUrl.toString() + '_blah';
if (ws !== null) {
ws.close();
@ -264,12 +264,12 @@ async function connectServer(newServerUrl) {
log('connecting server');
wsUrl.protocol = wsUrl.protocol == 'http:' ? 'ws:' : 'wss:';
wsUrl.pathname += wsUrl.pathname.endsWith('/') ? 'ws' : '/ws';
wsUrl.pathname += '_blah/ws';
ws = new WebSocket(wsUrl);
ws.onopen = async (_) => {
const auth = await signData({ typ: 'auth' });
await ws.send(auth);
log(`listening events on server: ${serverUrl}`);
log(`listening events on server: ${newServerUrl}`);
}
ws.onclose = (e) => {
console.error(e);
@ -310,7 +310,7 @@ async function loadRoomList(autoJoin) {
targetEl.value = '';
try {
const resp = await fetch(`${serverUrl}/room?filter=${filter}`, await genAuthHeader())
const resp = await fetch(`${apiUrl}/room?filter=${filter}`, await genAuthHeader())
const json = await resp.json()
if (resp.status !== 200) throw new Error(`status ${resp.status}: ${json.error.message}`);
for (const { rid, title, attrs, last_msg, last_seen_cid } of json.rooms) {
@ -343,7 +343,7 @@ async function loadRoomList(autoJoin) {
async function joinRoom(rid) {
try {
joinNewRoomInput.disabled = true;
await signAndPost(`${serverUrl}/room/${rid}/admin`, {
await signAndPost(`${apiUrl}/room/${rid}/admin`, {
// sorted fields.
permission: 1, // POST_CHAT
room: rid,
@ -363,7 +363,7 @@ async function joinRoom(rid) {
async function leaveRoom() {
try {
await signAndPost(`${serverUrl}/room/${curRoom}/admin`, {
await signAndPost(`${apiUrl}/room/${curRoom}/admin`, {
room: curRoom,
typ: 'remove_member',
user: await getActPubkey(),
@ -428,7 +428,7 @@ async function postChat(text) {
} else {
richText = [text];
}
await signAndPost(`${serverUrl}/room/${curRoom}/msg`, {
await signAndPost(`${apiUrl}/room/${curRoom}/msg`, {
// sorted fields.
rich_text: richText,
room: curRoom,
@ -445,7 +445,7 @@ async function postChat(text) {
async function markSeen() {
try {
const resp = await fetch(`${serverUrl}/room/${curRoom}/msg/${lastCid}/seen`, {
const resp = await fetch(`${apiUrl}/room/${curRoom}/msg/${lastCid}/seen`, {
method: 'POST',
headers: (await genAuthHeader()).headers,
})