Skip to content

Commit

Permalink
feat: read only handler
Browse files Browse the repository at this point in the history
Signed-off-by: Hoang Pham <[email protected]>
  • Loading branch information
hweihwang committed Jun 18, 2024
1 parent 03f28d4 commit 6606f6d
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 284 deletions.
37 changes: 34 additions & 3 deletions lib/Controller/WhiteboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Whiteboard\Controller;

use Firebase\JWT\JWT;
Expand Down Expand Up @@ -33,14 +34,42 @@ public function __construct(
parent::__construct($appName, $request);
}

/**
* @throws NotPermittedException
* @throws NoUserException

Check failure on line 39 in lib/Controller/WhiteboardController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedDocblockClass

lib/Controller/WhiteboardController.php:39:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OC\User\NoUserException does not exist (see https://psalm.dev/200)
* @throws \JsonException
*/
#[NoAdminRequired]
#[NoCSRFRequired]
#[PublicPage]
public function update(int $fileId, array $data): DataResponse {
$user = $this->userSession->getUser();
$userFolder = $this->rootFolder->getUserFolder($user?->getUID());
$authHeader = $this->request->getHeader('Authorization');

if (!$authHeader) {
return new DataResponse(['message' => 'Unauthorized'], Http::STATUS_UNAUTHORIZED);
}

[$jwt] = sscanf($authHeader, 'Bearer %s');

Check failure on line 52 in lib/Controller/WhiteboardController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

PossiblyUndefinedArrayOffset

lib/Controller/WhiteboardController.php:52:4: PossiblyUndefinedArrayOffset: Possibly undefined array key (see https://psalm.dev/167)

if (!$jwt) {
return new DataResponse(['message' => 'Unauthorized'], Http::STATUS_UNAUTHORIZED);
}

try {
$key = $this->config->getSystemValueString('jwt_secret_key');
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));

Check failure on line 60 in lib/Controller/WhiteboardController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

PossiblyInvalidArgument

lib/Controller/WhiteboardController.php:60:27: PossiblyInvalidArgument: Argument 1 of Firebase\JWT\JWT::decode expects string, but possibly different type float|int|non-falsy-string provided (see https://psalm.dev/092)
$userId = $decoded->userid;
} catch (\Exception $e) {
return new DataResponse(['message' => 'Unauthorized'], Http::STATUS_UNAUTHORIZED);
}

$userFolder = $this->rootFolder->getUserFolder($userId);
$file = $userFolder->getById($fileId)[0];

if (empty($data)) {
$data = ['elements' => [], 'scrollToContent' => true];
}

$file->putContent(json_encode($data, JSON_THROW_ON_ERROR));

return new DataResponse(['status' => 'success']);
Expand Down Expand Up @@ -79,9 +108,11 @@ public function show(int $fileId): DataResponse {
$file = $userFolder->getById($fileId)[0];

$fileContent = $file->getContent();
if ($fileContent === '') {

if (empty($fileContent)) {
$fileContent = '{"elements":[],"scrollToContent":true}';
}

$data = json_decode($fileContent, true, 512, JSON_THROW_ON_ERROR);

return new DataResponse([
Expand Down
249 changes: 0 additions & 249 deletions websocket_server/index.js

This file was deleted.

38 changes: 13 additions & 25 deletions websocket_server/roomData.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable no-console */
/* eslint-disable n/no-process-exit */

import fetch from 'node-fetch'
import dotenv from 'dotenv'
Expand All @@ -9,16 +8,15 @@ dotenv.config()
const {
NEXTCLOUD_URL = 'http://nextcloud.local',
ADMIN_USER = 'admin',
ADMIN_PASS = 'admin',
ADMIN_PASS = 'admin'
} = process.env
const FORCE_CLOSE_TIMEOUT = 60 * 1000

export let roomDataStore = {}
export const roomDataStore = {}

const fetchOptions = (method, token, body = null) => {
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
Authorization: `Bearer ${token}`
}

if (method === 'PUT') {
Expand All @@ -28,7 +26,7 @@ const fetchOptions = (method, token, body = null) => {
return {
method,
headers,
...(body && { body: JSON.stringify(body) }),
...(body && { body: JSON.stringify(body) })
}
}

Expand Down Expand Up @@ -58,6 +56,7 @@ export const getRoomDataFromFile = async (roomID, socket) => {
return result ? result.data.elements : null
}

// Called when there's nobody in the room (No one keeping the latest data), BE to BE communication
export const saveRoomDataToFile = async (roomID, data) => {
console.log(`Saving room data to file: ${roomID}`)
const url = `${NEXTCLOUD_URL}/index.php/apps/whiteboard/${roomID}`
Expand All @@ -67,27 +66,16 @@ export const saveRoomDataToFile = async (roomID, data) => {
await fetchData(url, options)
}

// TODO: Should be called when the server is shutting down and a should be a BE to BE (or OS) communication
// in batch operation, run in background and check if it's necessary to save for each room.
// Should be called periodically and saved somewhere else for preventing data loss (memory loss, server crash, electricity cut, etc.)
export const saveAllRoomsData = async () => {
}

export const removeAllRoomData = async () => {
for (const roomID in roomDataStore) {
if (Object.prototype.hasOwnProperty.call(roomDataStore, roomID) && roomDataStore[roomID]) {
await saveRoomDataToFile(roomID, roomDataStore[roomID])
if (Object.prototype.hasOwnProperty.call(roomDataStore, roomID)) {
delete roomDataStore[roomID]
}
}
}

export const gracefulShutdown = async (server) => {
console.log('Received shutdown signal, saving all data...')
await saveAllRoomsData()
console.log('All data saved, shutting down server...')
roomDataStore = {}

server.close(() => {
console.log('HTTP server closed.')
process.exit(0)
})

setTimeout(() => {
console.error('Force closing server after 1 minute.')
process.exit(1)
}, FORCE_CLOSE_TIMEOUT)
}
Loading

0 comments on commit 6606f6d

Please sign in to comment.