mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 20:59:05 +00:00
feat: add room by name endpoint for non-authenticated access
- Add GET /rooms/name/{room_name} backend endpoint
- Endpoint supports non-authenticated access for public rooms
- Returns RoomDetails with webhook fields hidden for non-owners
- Update useRoomGetByName hook to use new direct endpoint
- Remove authentication requirement from frontend hook
- Regenerate API client types
Fixes: Non-authenticated users can now access room lobbies
This commit is contained in:
@@ -155,6 +155,30 @@ async def rooms_get(
|
|||||||
return room
|
return room
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/rooms/name/{room_name}", response_model=RoomDetails)
|
||||||
|
async def rooms_get_by_name(
|
||||||
|
room_name: str,
|
||||||
|
user: Annotated[Optional[auth.UserInfo], Depends(auth.current_user_optional)],
|
||||||
|
):
|
||||||
|
user_id = user["sub"] if user else None
|
||||||
|
room = await rooms_controller.get_by_name(room_name)
|
||||||
|
if not room:
|
||||||
|
raise HTTPException(status_code=404, detail="Room not found")
|
||||||
|
|
||||||
|
# Convert to RoomDetails format (add webhook fields if user is owner)
|
||||||
|
room_dict = room.__dict__.copy()
|
||||||
|
if user_id == room.user_id:
|
||||||
|
# User is owner, include webhook details if available
|
||||||
|
room_dict["webhook_url"] = getattr(room, "webhook_url", None)
|
||||||
|
room_dict["webhook_secret"] = getattr(room, "webhook_secret", None)
|
||||||
|
else:
|
||||||
|
# Non-owner, hide webhook details
|
||||||
|
room_dict["webhook_url"] = None
|
||||||
|
room_dict["webhook_secret"] = None
|
||||||
|
|
||||||
|
return RoomDetails(**room_dict)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/rooms", response_model=Room)
|
@router.post("/rooms", response_model=Room)
|
||||||
async def rooms_create(
|
async def rooms_create(
|
||||||
room: CreateRoom,
|
room: CreateRoom,
|
||||||
|
|||||||
@@ -642,19 +642,16 @@ export function useRoomsCreateMeeting() {
|
|||||||
|
|
||||||
// Calendar integration hooks
|
// Calendar integration hooks
|
||||||
export function useRoomGetByName(roomName: string | null) {
|
export function useRoomGetByName(roomName: string | null) {
|
||||||
const { isAuthenticated } = useAuthReady();
|
|
||||||
|
|
||||||
return $api.useQuery(
|
return $api.useQuery(
|
||||||
"get",
|
"get",
|
||||||
"/v1/rooms",
|
"/v1/rooms/name/{room_name}",
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
query: { page: 1 }, // We'll need to filter by room name on the client side
|
path: { room_name: roomName || "" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!roomName && isAuthenticated,
|
enabled: !!roomName,
|
||||||
select: (data) => data.items?.find((room) => room.name === roomName),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
84
www/app/reflector-api.d.ts
vendored
84
www/app/reflector-api.d.ts
vendored
@@ -98,6 +98,23 @@ export interface paths {
|
|||||||
patch: operations["v1_rooms_update"];
|
patch: operations["v1_rooms_update"];
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/v1/rooms/name/{room_name}": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
/** Rooms Get By Name */
|
||||||
|
get: operations["v1_rooms_get_by_name"];
|
||||||
|
put?: never;
|
||||||
|
post?: never;
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/v1/rooms/{room_name}/meeting": {
|
"/v1/rooms/{room_name}/meeting": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
@@ -656,11 +673,9 @@ export interface components {
|
|||||||
*/
|
*/
|
||||||
end_time: string;
|
end_time: string;
|
||||||
/** Attendees */
|
/** Attendees */
|
||||||
attendees?:
|
attendees?: {
|
||||||
| {
|
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}[]
|
}[] | null;
|
||||||
| null;
|
|
||||||
/** Location */
|
/** Location */
|
||||||
location?: string | null;
|
location?: string | null;
|
||||||
/**
|
/**
|
||||||
@@ -756,13 +771,7 @@ export interface components {
|
|||||||
* Status
|
* Status
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
status:
|
status: "idle" | "uploaded" | "recording" | "processing" | "error" | "ended";
|
||||||
| "idle"
|
|
||||||
| "uploaded"
|
|
||||||
| "recording"
|
|
||||||
| "processing"
|
|
||||||
| "error"
|
|
||||||
| "ended";
|
|
||||||
/** Locked */
|
/** Locked */
|
||||||
locked: boolean;
|
locked: boolean;
|
||||||
/** Duration */
|
/** Duration */
|
||||||
@@ -810,13 +819,7 @@ export interface components {
|
|||||||
* Status
|
* Status
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
status:
|
status: "idle" | "uploaded" | "recording" | "processing" | "error" | "ended";
|
||||||
| "idle"
|
|
||||||
| "uploaded"
|
|
||||||
| "recording"
|
|
||||||
| "processing"
|
|
||||||
| "error"
|
|
||||||
| "ended";
|
|
||||||
/** Locked */
|
/** Locked */
|
||||||
locked: boolean;
|
locked: boolean;
|
||||||
/** Duration */
|
/** Duration */
|
||||||
@@ -1031,11 +1034,7 @@ export interface components {
|
|||||||
* @default automatic-2nd-participant
|
* @default automatic-2nd-participant
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
recording_trigger:
|
recording_trigger: "none" | "prompt" | "automatic" | "automatic-2nd-participant";
|
||||||
| "none"
|
|
||||||
| "prompt"
|
|
||||||
| "automatic"
|
|
||||||
| "automatic-2nd-participant";
|
|
||||||
/**
|
/**
|
||||||
* Num Clients
|
* Num Clients
|
||||||
* @default 0
|
* @default 0
|
||||||
@@ -1247,13 +1246,7 @@ export interface components {
|
|||||||
* Status
|
* Status
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
status:
|
status: "idle" | "uploaded" | "recording" | "processing" | "error" | "ended";
|
||||||
| "idle"
|
|
||||||
| "uploaded"
|
|
||||||
| "recording"
|
|
||||||
| "processing"
|
|
||||||
| "error"
|
|
||||||
| "ended";
|
|
||||||
/** Rank */
|
/** Rank */
|
||||||
rank: number;
|
rank: number;
|
||||||
/**
|
/**
|
||||||
@@ -1727,6 +1720,37 @@ export interface operations {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
v1_rooms_get_by_name: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path: {
|
||||||
|
room_name: string;
|
||||||
|
};
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody?: never;
|
||||||
|
responses: {
|
||||||
|
/** @description Successful Response */
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["RoomDetails"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description Validation Error */
|
||||||
|
422: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["HTTPValidationError"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
v1_rooms_create_meeting: {
|
v1_rooms_create_meeting: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|||||||
Reference in New Issue
Block a user