From 6026501405f94c82a2d1bd9f0e79f2dea42aaeaa Mon Sep 17 00:00:00 2001 From: "Alex.exe" <40430040+NfoAlex@users.noreply.github.com> Date: Tue, 13 Aug 2024 19:27:03 +0900 Subject: [PATCH] Better sqlite3 (#60) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [add] - better-sqlite3 * [add] - @types/better-sqlite3 * [change] - authLoginをbetter-sqlite3化 * [fix] - better-sqlite3のデータ無かった時の型が違っていた * [change] - fetchUserをbetter-sqlite3へ * [change] - 変数名 * [add] - コメント * [change] - checkSessionをbetter-sqlite3へ * [change] - こだわり * [fix] - ユーザー情報のパース忘れてた * [add] - authRegisterをbetter-sqlite3へ * [change] - changePasswordをbetter-sqlite3へ * [fix] - 忘れてた * [change] - fetchSessionをbetter-sqlite3へ * [remove] - また忘れてた * [change] - changeSessionNameをbetter-sqlite3へ * [change] - sessionLogoutをbetter-sqlite3へ * [remove] - ログ無効化 * [add] - type * [change] - createChannelをbetter-sqlite3へ * [change] - チャンネル取得関数の処理方法改善 * [remove] - 不要なログ * [change] - roleCheckをbetter-sqlite3へ * [change] - エラーコード変更 * [change] - deleteChannelをbetter-sqlite3へ * [change] - updateChannelをbetter-sqlite3へ * [remove] - sqlite3のコード * [change] - fetchChannelをbetter-sqlite3へ * [change] - fetchChannelListをbetter-sqlite3へ * [change] - joinChannelをbetter-sqlite3へ * [remove] - 忘れてた * [change] - leaveChannelをbetter-sqlite3へ * [add] - チャンネル作成時に履歴テーブルを作るように * [change] - saveMessageをbetter-sqlite3へ * [change] - genLinkPreviewをbetter-sqlite3へ * [change] - deleteMessageをbetter-sqlite3へ * [add] - type付け * [change] - editMessageをbetter-sqlite3へ * [change] - fetchHistoryをbetter-sqlite3へ * [remove] * [change] - 変数名 * [change] - reactMessageをbetter-sqlite3へ * [add] - コメント * [change] - setMessageReadTimeをbetter-sqlite3へ * [change] - getMessageReadTimeをbetter-sqlite3へ * [remove] - getMessageReadTimeからasyncを削除 * [change] - fetchFileIndexをbetter-sqlite3へ * [change] - fetchFileInfoをbetter-sqlite3へ * [change] - deleteFileをbetter-sqlite3へ * [remove] - await * [change] - fetchFoldersをbetter-sqlite3へ * [change] - 変数名とコメント * [change] - calcFullFolderSizeをbetter-sqlite3へ * [remove] - ログ * [change] - toggleFileIsPublicをbetter-sqlite3へ * [remove] - await * [change] - createFolderをbetter-sqlite3へ * [change] - deleteFoldersをbetter-sqlite3へ * [fetchUserをasyncじゃなくした * [remove] - await * [change] - fetchMessageをbetter-sqlite3へ * [change] - fetchOnlineUsersをbetter-sqlite-3へ * [remove] - await * [fix] - ファイル名 * [change] - addUserOnlineをbetter-sqlite3へ * [remove] - 不要なimport * [change] - fetchRolesをbetter-sqlite3へ * [remove] - await * [change] - searchRoleをbetter-sqlite3へ * [change] - 変数名 * [change] - fetchRoleSingleをbetter-sqlite3へ * [change] - addRoleをbetter-sqlite3へ * [change] - roleCheckからasync削除 * [change] - calcRoleUserのelse省略 * [remove] - ロール系関数のasync削除 * [change] - unlinkRoleをbetter-sqlite3へ * [change] - createRoleをbetter-sqlite3へ * [change] - updateRoleをbetter-sqlite3へ * [change] - deleteRoleをbetter-sqlite3へ * [change] - Server系処理のコード整理 * [change] - fetchUserConfigをbetter-sqlite3へ * [remove] - 不要なログ * [change] - fetchUserChannelOrderをbetter-sqlite3へ * [change] - fetchUserInboxをbetter-sqlite3へ * [change] - removeFromUserInboxをbetter-sqlite3へ 削除キューシステムは念のため残す * [change] - saveUserConfigをbetter-sqlite3へ * [change] - saveUserChannelOrderをbetter-sqlite3へ * [change] - fetchUserAllをbetter-sqlite3へ * [change] - searchUserをbetter-sqlite3へ * [change] - changeUserNameをbetter-sqlite3へ * [change] - 自分標的のBAN時のエラーコード変更 * [change] - banUserをbetter-sqlite3へ * [change]- pardonUserをbetter-sqlite3へ * [change] - removeUserOnlineBySocketIdをbetter-sqlite3へ * [remove] - 不要なファイル * Biome Check * [change] - uploadfileをbetter-sqlite3へ * Biome Check fetchfile * Biome Check downloadfile * [add] - node: * [change] - Fileからawait削除 * [remove/change] - Message系Socketハンドラからasyncとawait排除 * [remove] - ここもいらない * [remove] - File系Socketハンドラからawaitとasync排除 * [remove] - Channel系Socketハンドラからawaitとasync排除 * [remove] - User系Socketハンドラからawaitとasync排除 * [remove] - Server系Socketハンドラからasyncとawait排除 * [change] - auth系Socketハンドラからawaitとasync排除 --- package-lock.json | 21 ++ package.json | 2 + src/INDEX.ts | 10 +- src/actionHandler/Channel/createChannel.ts | 91 +++-- src/actionHandler/Channel/deleteChannel.ts | 48 ++- src/actionHandler/Channel/fetchChannel.ts | 103 +++--- src/actionHandler/Channel/fetchChannelList.ts | 94 +++-- src/actionHandler/Channel/joinChannel.ts | 97 +++--- src/actionHandler/Channel/leaveChannel.ts | 83 ++--- src/actionHandler/Channel/updateChannel.ts | 69 ++-- src/actionHandler/File/calcFullFolderSize.ts | 12 +- src/actionHandler/File/createFolder.ts | 48 +-- src/actionHandler/File/deleteFile.ts | 47 ++- src/actionHandler/File/deleteFolder.ts | 56 ++- src/actionHandler/File/fetchFileIndex.ts | 56 ++- src/actionHandler/File/toggleFileIsPublic.ts | 45 ++- src/actionHandler/Message/deleteMessage.ts | 52 ++- src/actionHandler/Message/editMessage.ts | 69 ++-- src/actionHandler/Message/fetchHistory.ts | 325 ++++++++---------- src/actionHandler/Message/fetchMessage.ts | 70 ++-- .../Message/getMessageReadTime.ts | 49 ++- src/actionHandler/Message/reactMessage.ts | 71 ++-- src/actionHandler/Message/saveMessage.ts | 154 ++++----- .../Message/setMessageReadTime.ts | 62 ++-- src/actionHandler/Role/addRole.ts | 69 ++-- src/actionHandler/Role/calcRoleData.ts | 21 +- src/actionHandler/Role/calcRoleUser.ts | 24 +- src/actionHandler/Role/createRole.ts | 78 ++--- src/actionHandler/Role/deleteRole.ts | 25 +- src/actionHandler/Role/fetchRoleSingle.ts | 62 ++-- src/actionHandler/Role/fetchRoles.ts | 61 ++-- src/actionHandler/Role/searchRole.ts | 94 ++--- src/actionHandler/Role/unlinkRole.ts | 63 ++-- src/actionHandler/Role/updateRole.ts | 89 +++-- .../Server/updateServerConfig.ts | 4 +- src/actionHandler/Server/updateServerInfo.ts | 2 +- src/actionHandler/User/banUser.ts | 43 ++- src/actionHandler/User/changeUserName.ts | 38 +- src/actionHandler/User/fetchUser.ts | 105 +++--- src/actionHandler/User/fetchUserAll.ts | 107 +++--- .../User/fetchUserChannelOrder.ts | 40 ++- src/actionHandler/User/fetchUserConfig.ts | 80 ++--- src/actionHandler/User/fetchUserInbox.ts | 45 ++- src/actionHandler/User/pardonUser.ts | 48 +-- src/actionHandler/User/removeFromUserInbox.ts | 62 ++-- .../User/saveUserChannelOrder.ts | 56 ++- src/actionHandler/User/saveUserConfig.ts | 65 ++-- src/actionHandler/User/searchUser.ts | 91 ++--- src/actionHandler/auth/authLogin.ts | 56 ++- src/actionHandler/auth/authRegister.ts | 85 +++-- src/actionHandler/auth/changePassword.ts | 98 +++--- src/actionHandler/auth/changeSessionName.ts | 33 +- src/actionHandler/auth/checkSession.ts | 99 +++--- src/actionHandler/auth/fetchSession.ts | 31 +- src/actionHandler/auth/sessionLogout.ts | 29 +- .../onlineUsers/fetchOnlineUsers.ts | 42 +-- src/fileHandler/File/downloadfile.ts | 46 +-- src/fileHandler/File/fetchFolderInfo.ts | 48 +-- src/fileHandler/File/fetchfile.ts | 34 +- src/fileHandler/File/uploadfile.ts | 136 ++++---- src/fileHandler/FileHandler.ts | 26 +- src/socketHandler/Channel.ts | 54 +-- src/socketHandler/File.ts | 50 +-- src/socketHandler/Message.ts | 48 +-- src/socketHandler/OnlineUsers.ts | 10 +- src/socketHandler/Role.ts | 32 +- src/socketHandler/Server.ts | 23 +- src/socketHandler/User.ts | 114 +++--- src/socketHandler/auth.ts | 46 +-- src/util/FIle/calcDirectorySize.ts | 162 +++------ src/util/FIle/fetchFileInfo.ts | 46 +-- src/util/FIle/fetchFolders.ts | 53 ++- src/util/checkDataIntegrality.ts | 37 -- src/util/genLinkPreview.ts | 62 ++-- src/util/onlineUsers/addUserOnline.ts | 35 +- .../onlineUsers/removeUserOnlineBySocketId.ts | 100 ++---- src/util/roleCheck.ts | 105 +++--- 77 files changed, 2213 insertions(+), 2633 deletions(-) delete mode 100644 src/util/checkDataIntegrality.ts diff --git a/package-lock.json b/package-lock.json index c599c430..bba9be18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "dependencies": { + "better-sqlite3": "^11.1.2", "express": "^4.18.3", "install": "^0.13.0", "multer": "^1.4.5-lts.1", @@ -13,6 +14,7 @@ "sqlite3": "^5.1.7" }, "devDependencies": { + "@types/better-sqlite3": "^7.6.11", "@types/multer": "^1.4.11", "ts-node": "^10.9.2", "typescript": "^5.3.3" @@ -135,6 +137,15 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/better-sqlite3": { + "version": "7.6.11", + "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.11.tgz", + "integrity": "sha512-i8KcD3PgGtGBLl3+mMYA8PdKkButvPyARxA7IQAd6qeslht13qxb1zzO8dRCtE7U3IoJS782zDBAeoKiM695kg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -447,6 +458,16 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/better-sqlite3": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.1.2.tgz", + "integrity": "sha512-gujtFwavWU4MSPT+h9B+4pkvZdyOUkH54zgLdIrMmmmd4ZqiBIrRNBzNzYVFO417xo882uP5HBu4GjOfaSrIQw==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", diff --git a/package.json b/package.json index e4dff707..09c7b654 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "better-sqlite3": "^11.1.2", "express": "^4.18.3", "install": "^0.13.0", "multer": "^1.4.5-lts.1", @@ -8,6 +9,7 @@ "sqlite3": "^5.1.7" }, "devDependencies": { + "@types/better-sqlite3": "^7.6.11", "@types/multer": "^1.4.11", "ts-node": "^10.9.2", "typescript": "^5.3.3" diff --git a/src/INDEX.ts b/src/INDEX.ts index 1974b398..d7941508 100644 --- a/src/INDEX.ts +++ b/src/INDEX.ts @@ -1,8 +1,8 @@ // 実行 :: npx ts-node ./src/INDEX.ts -import fs from "fs"; -import { createServer } from "http"; -import { Server, Socket } from "socket.io"; +import fs from "node:fs"; +import { createServer } from "node:http"; +import { Server, type Socket } from "socket.io"; import express from "express"; const app = express(); @@ -56,8 +56,8 @@ io.on("connection", (socket:Socket) => { //ユーザーから切断されたとき socket.on("disconnect", async () => { //接続を削除 - const userIdDisconnecting = await removeUserOnlineBySocketId(socket.id); - //ログイン中の全員に切断されたユーザーIdを返す + const userIdDisconnecting = removeUserOnlineBySocketId(socket.id); + //完全に切断されたのなら(nullじゃない)、ログイン中のユーザー全員に通知 if (userIdDisconnecting !== null) { io.to("LOGGEDIN").emit("removeOnlineUser", {data:userIdDisconnecting}); } diff --git a/src/actionHandler/Channel/createChannel.ts b/src/actionHandler/Channel/createChannel.ts index d5cbf017..cfb1bb97 100644 --- a/src/actionHandler/Channel/createChannel.ts +++ b/src/actionHandler/Channel/createChannel.ts @@ -1,47 +1,64 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/SERVER.db"); -import fetchUser from "../User/fetchUser"; import fetchChannel from "./fetchChannel"; +import Database from 'better-sqlite3'; +const db = new Database('./records/SERVER.db'); +db.pragma('journal_mode = WAL'); + +/** + * チャンネルを作成する + * @param channelName + * @param description + * @param isPrivate + * @param userId + * @returns + */ export default async function createChannel( - channelName:string, - description:string, - isPrivate:boolean, - userId:string, + _channelName:string, + _description:string, + _isPrivate:boolean, + _userId:string, ):Promise { try { - return new Promise(async (resolve) => { - //TODO :: ロールチェック + //空いているチャンネルIDを探して取得 + const channelIdGen = await getNewChannelId(); + //IDが空なら失敗として返す + if (channelIdGen === "") return false; - //空いているチャンネルIDを探して取得 - const channelIdGen = await getNewChannelId(); - //IDが空なら失敗として返す - if (channelIdGen === "") return false; + //チャンネル用履歴テーブル作成 + db.exec( + ` + create table if not exists C${channelIdGen}( + messageId TEXT PRIMARY KEY, + channelId TEXT NOT NULL, + userId TEXT NOT NULL, + content TEXT NOT NULL, + isEdited BOOLEAN NOT NULL DEFAULT '0', + linkData TEXT DEFAULT '{}', + fileId TEXT NOT NULL, + time TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')), + reaction TEXT NOT NULL + ) + ` + ); - //チャンネルデータを挿入 - return db.run(` - INSERT INTO CHANNELS ( - channelId, channelName, description, createdBy, isPrivate, speakableRole - ) - values (?,?,?,?,?,?) - `, - channelIdGen, - channelName, - description, - userId, - isPrivate, - "", - (err:Error) => { //結果処理 - //エラーなら失敗と返し、無事ならtrueを返す - if (err) { - resolve(false); - } else { - resolve(true); - } - } - ); - }); + db.prepare( + ` + INSERT INTO CHANNELS ( + channelId, channelName, description, createdBy, isPrivate, speakableRole + ) + values (?,?,?,?,?,?) + ` + ).run( + channelIdGen, + _channelName, + _description, + _userId, + _isPrivate?1:0, + "" + ); + + return true; } catch(e) { @@ -53,7 +70,7 @@ export default async function createChannel( //チャンネルIDの空きを探す async function getNewChannelId():Promise { - let tryCount:number = 0; + let tryCount = 0; return new Promise((resolve) => { try { diff --git a/src/actionHandler/Channel/deleteChannel.ts b/src/actionHandler/Channel/deleteChannel.ts index 5928f405..37a0e3f8 100644 --- a/src/actionHandler/Channel/deleteChannel.ts +++ b/src/actionHandler/Channel/deleteChannel.ts @@ -1,46 +1,40 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/SERVER.db"); import fetchChannel from "./fetchChannel"; import roleCheck from "../../util/roleCheck"; -export default async function deleteChannel( - userId: string, - channelId: string - ):Promise { +import Database from 'better-sqlite3'; +const db = new Database('./records/SERVER.db'); +db.pragma('journal_mode = WAL'); + +/** + * チャンネルを削除する + * @param _userId 削除する操作元のユーザーId + * @param _channelId 削除するチャンネルId + * @returns + */ +export default function deleteChannel( + _userId: string, + _channelId: string + ):boolean { try { //チャンネル情報を取得 - const channelInfo = await fetchChannel(channelId, userId); + const channelInfo = fetchChannel(_channelId, _userId); //無ければ停止 if (channelInfo === null) return false; //チャンネル作成者でない場合権限があるかを確認 - if (channelInfo.createdBy !== userId) { + if (channelInfo.createdBy !== _userId) { //チャンネル管理のロール権限を確認する - const roleCheckResult = await roleCheck(userId, "ChannelManage"); + const roleCheckResult = roleCheck(_userId, "ChannelManage"); if (!roleCheckResult) { //falseなら停止 return false; } } - return new Promise((resolve) => { - //テーブルからチャンネルを削除 - db.run( - "DELETE FROM CHANNELS WHERE channelId=?", - channelId, - (err) => { - //結果に応じてbooleanで結果を返す - if (err) { - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - - }); + //チャンネルのテーブルを削除 + db.prepare("DELETE FROM CHANNELS WHERE channelId=?").run(_channelId); + + return true; } catch(e) { diff --git a/src/actionHandler/Channel/fetchChannel.ts b/src/actionHandler/Channel/fetchChannel.ts index f52792f2..7432c7b3 100644 --- a/src/actionHandler/Channel/fetchChannel.ts +++ b/src/actionHandler/Channel/fetchChannel.ts @@ -1,59 +1,56 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/SERVER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/SERVER.db'); +db.pragma('journal_mode = WAL'); + import fetchUser from "../User/fetchUser"; import roleCheck from "../../util/roleCheck"; import type { IChannelbeforeParsing, IChannel } from "../../type/Channel"; -export default async function fetchChannel(channelId:string, userId:string) -:Promise { - return new Promise(async (resolve) => { - db.all("SELECT * FROM CHANNELS WHERE channelId = ?", [channelId], async (err:Error, datChannels:IChannelbeforeParsing[]) => { - if (err) { - console.log("fetchChannel :: db : エラー->", err); - resolve(null); - return; - } else { - //console.log("fetchChannel :: db : 取得結果->", datChannels); - //チャンネルデータが無ければnull、あれば整形して返す - if (datChannels.length === 0) { - resolve(null); - return; - } else { - //プラベなら権限と参加を調べて無いならnull - if (datChannels[0].isPrivate) { - //ユーザー情報を取得 - const userInfo = await fetchUser(userId, null); - //ユーザー情報がそもそもないならnull - if (userInfo === null) { - resolve(null); - return; - } - - //このユーザーがサーバー管理権限がありプラベを見られるか調べる - if ( - !userInfo.channelJoined.includes(channelId) - && - !(await roleCheck(userId, "ServerManage")) - ) { - //返す - resolve(null); - return; - } - } - - //チャンネル情報を整形する - const infoGotIt:IChannel = { - ...datChannels[0], - isPrivate: datChannels[0].isPrivate===1?true:false, - speakableRole: //空文字列なら空配列にする - datChannels[0].speakableRole!==""?datChannels[0].speakableRole.split(","):[] - }; - //返す - resolve(infoGotIt); - return; - } - } - }); - }); +/** + * チャンネル情報を取得する + * @param _channelId + * @param _userId + * @returns + */ +export default function fetchChannel(_channelId:string, _userId:string) +:IChannel|null { + try { + + const channelInfo = db.prepare( + "SELECT * FROM CHANNELS WHERE channelId=?" + ).get(_channelId) as IChannelbeforeParsing|undefined; + + if (channelInfo === undefined) return null; + + //プライベートならユーザーの権限、あるいは作成者と同じか調べる + if (channelInfo.isPrivate) { + //ユーザー情報を取得 + const userInfo = fetchUser(_userId, null); + if (userInfo === null) return null; + + //チャンネル作成者と同じか、あるいはサーバー管理権限があるか調べる + if ( + !userInfo.channelJoined.includes(_channelId) + && + !(roleCheck(_userId, "ServerManage")) + ) return null; + } + + //チャンネル情報をパースする + const channelInfoParsed:IChannel = { + ...channelInfo, + isPrivate: channelInfo.isPrivate === 1, + speakableRole: //👇空文字列なら空配列にする + channelInfo.speakableRole!==""?channelInfo.speakableRole.split(","):[] + } + + return channelInfoParsed; + + } catch(e) { + + console.log("fetchChannel :: エラー->", e); + return null; + + } } diff --git a/src/actionHandler/Channel/fetchChannelList.ts b/src/actionHandler/Channel/fetchChannelList.ts index a847ca49..69896774 100644 --- a/src/actionHandler/Channel/fetchChannelList.ts +++ b/src/actionHandler/Channel/fetchChannelList.ts @@ -1,40 +1,62 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/SERVER.db"); import fetchUser from "../User/fetchUser"; import roleCheck from "../../util/roleCheck"; -import type { IChannel } from "../../type/Channel"; - -export default async function fetchChannelList(userId: string) -:Promise { - - //ユーザー情報を取得、ないならnull - const userInfo = await fetchUser(userId, null); - if (userInfo === null) return null; - - //このユーザーがサーバー管理権限がありプラベを見られるか調べる - const roleServerManage = await roleCheck(userId, "ServerManage"); - - return new Promise((resolve) => { - db.all("SELECT * FROM CHANNELS", (err:Error, datChannels:IChannel[]) => { - if (err) { - console.log("fetchChannelList :: db : エラー->", err); - resolve(null); - } else { - //プラベチャンネルを見れる権限があるなら参加確認しない - if (!roleServerManage) { - //権限を持っておらず、参加していないなら除去 - let datChannelsFiltered = datChannels.filter((channel) => { - return userInfo.channelJoined.includes(channel.channelId) - || - !channel.isPrivate - }); - - resolve(datChannelsFiltered); - } else { - resolve(datChannels); - } - } - }); - }); +import Database from 'better-sqlite3'; +const db = new Database('./records/SERVER.db'); +db.pragma('journal_mode = WAL'); + +import type { IChannel, IChannelbeforeParsing } from "../../type/Channel"; + +/** + * チャンネル情報を一括で取得 + * @param _userId + * @returns + */ +export default async function fetchChannelList(_userId: string) +:Promise { + try { + + //ユーザー情報を取得、ないならnull + const userInfo = fetchUser(_userId, null); + if (userInfo === null) return null; + + //このユーザーがサーバー管理権限がありプラベを見られるか調べる + const roleServerManage = roleCheck(_userId, "ServerManage"); + + //チャンネル情報を一括取得 + const channelList = db.prepare( + "SELECT * FROM CHANNELS" + ).all() as IChannelbeforeParsing[]; + + //チャンネルリストから自分の権限でみられるチャンネルのみにフィルターする + let channelListFiltered:IChannelbeforeParsing[] = []; + //サーバー管理権限がないならフィルター、ないならそのまま格納 + if (!roleServerManage) { + channelListFiltered = channelList.filter((channel) => { + return userInfo.channelJoined.includes(channel.channelId) + || + !channel.isPrivate; + }); + } else { + channelListFiltered = channelList; + } + + //チャンネル情報をパースする + const channelListParsed:IChannel[] = []; + for (const channel of channelListFiltered) { + channelListParsed.push({ + ...channel, + isPrivate: channel.isPrivate === 1, + speakableRole: channel.speakableRole.split(",") + }); + } + + return channelListParsed; + + } catch(e) { + + console.log("fetchChannelList :: エラー->", e); + return null; + + } } diff --git a/src/actionHandler/Channel/joinChannel.ts b/src/actionHandler/Channel/joinChannel.ts index f261d03e..2803126a 100644 --- a/src/actionHandler/Channel/joinChannel.ts +++ b/src/actionHandler/Channel/joinChannel.ts @@ -1,65 +1,52 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); import fetchUser from "../User/fetchUser"; import fetchChannel from "./fetchChannel"; -export default async function joinChannel(userId:string, channelId:string) -:Promise { +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + +/** + * チャンネルへ参加させる + * @param _userId + * @param _channelId + * @returns + */ +export default function joinChannel(_userId:string, _channelId:string) +:boolean { try { - - return new Promise(async (resolve) => { - //チャンネルの存在を確認しないなら停止 - if (await fetchChannel(channelId, userId) === null) { - resolve(false); - return; - } - - //TODO :: ロール確認(ChannelViewPrivate) - //現在のユーザー情報を取得 - const userInfo = await fetchUser(userId, null); - //情報が空なら処理停止 - if (userInfo === null) { - resolve(false); - return; - } - //参加しているチャンネルの配列抜き出し - const channelJoinedArr = userInfo.channelJoined; - - //参加チャンネル配列にすでにチャンネルIDが入ってるなら停止 - if (channelJoinedArr.includes(channelId)) { - resolve(false); - return; - } + //チャンネルの存在を確認しないなら停止 + if (fetchChannel(_channelId, _userId) === null) { + return false; + } + + //現在のユーザー情報を取得 + const userInfo = fetchUser(_userId, null); + //情報が空なら処理停止 + if (userInfo === null) { + return false; + } + //参加しているチャンネルの配列抜き出し + const channelJoinedArr = userInfo.channelJoined; + + //参加チャンネル配列にすでにチャンネルIDが入ってるなら停止 + if (channelJoinedArr.includes(_channelId)) { + return false; + } + + //参加配列が空([""])なら代入、違うならチャンネルIDを配列へ追加 + if (channelJoinedArr.length === 1 && channelJoinedArr[0] === "") { + channelJoinedArr[0] = _channelId; + } else { + channelJoinedArr.push(_channelId); + } - //参加配列が空([""])なら代入、違うならチャンネルIDを配列へ追加 - if (channelJoinedArr.length === 1 && channelJoinedArr[0] === "") { - channelJoinedArr[0] = channelId; - } else { - channelJoinedArr.push(channelId); - } + //ユーザーのレコードへ挿入 + db.prepare( + "UPDATE USERS_INFO SET channelJoined=? WHERE userId=?" + ).run(channelJoinedArr.join(","), _userId); - //DBにて更新 - db.run( - "UPDATE USERS_INFO SET channelJoined=? WHERE userId=?", - [ - channelJoinedArr.join(","), //更新した参加チャンネル配列 - userId //参加するユーザーID - ], - (err) => { - if (err) { - console.log("joinChannel :: db : エラー->", err); - //エラーなら失敗 - resolve(false); - return; - } else { - //無事なら成功 - resolve(true); - return; - } - } - ); - }); + return true; } catch(e) { diff --git a/src/actionHandler/Channel/leaveChannel.ts b/src/actionHandler/Channel/leaveChannel.ts index a59d265c..374ea2b5 100644 --- a/src/actionHandler/Channel/leaveChannel.ts +++ b/src/actionHandler/Channel/leaveChannel.ts @@ -1,55 +1,42 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); import fetchUser from "../User/fetchUser"; -export default async function leaveChannel(userId:string, channelId:string) -:Promise { +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + +/** + * チャンネルから脱退する + * @param _userId + * @param _channelId + * @returns + */ +export default function leaveChannel(_userId:string, _channelId:string) +:boolean { try { - return new Promise(async (resolve) => { - - //TODO :: ロール確認(ChannelViewPrivate) - - //現在のユーザー情報を取得 - const userInfo = await fetchUser(userId, null); - //情報が空なら処理停止 - if (userInfo === null) { - resolve(false); - return; - } - //参加しているチャンネルの配列抜き出し - const channelJoinedArr = userInfo.channelJoined; - - //参加チャンネル配列にチャンネルIDが無いなら停止 - if (!channelJoinedArr.includes(channelId)) { - resolve(false); - return; - } - - //チャンネルIDを配列から削除 - channelJoinedArr.splice(channelJoinedArr.indexOf(channelId), 1); - - //DBにて更新 - db.run( - "UPDATE USERS_INFO SET channelJoined=? WHERE userId=?", - [ - channelJoinedArr.join(","), //更新した参加チャンネル配列 - userId //参加するユーザーID - ], - (err) => { - if (err) { - console.log("leaveChannel :: db : エラー->", err); - //エラーなら失敗 - resolve(false); - return; - } else { - //無事なら成功 - resolve(true); - return; - } - } - ); - }); + //現在のユーザー情報を取得 + const userInfo = fetchUser(_userId, null); + //情報が空なら処理停止 + if (userInfo === null) { + return false; + } + //参加しているチャンネルの配列抜き出し + const channelJoinedArr = userInfo.channelJoined; + + //参加チャンネル配列にチャンネルIDが無いなら停止 + if (!channelJoinedArr.includes(_channelId)) { + return false; + } + + //チャンネルIDを配列から削除 + channelJoinedArr.splice(channelJoinedArr.indexOf(_channelId), 1); + + //テーブルへチャンネル参加配列を適用 + db.prepare( + "UPDATE USERS_INFO SET channelJoined=? WHERE userId=?" + ).run(channelJoinedArr.join(","), _userId); + + return true; } catch(e) { diff --git a/src/actionHandler/Channel/updateChannel.ts b/src/actionHandler/Channel/updateChannel.ts index fb6f92b5..dda4b506 100644 --- a/src/actionHandler/Channel/updateChannel.ts +++ b/src/actionHandler/Channel/updateChannel.ts @@ -1,46 +1,47 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/SERVER.db"); import roleCheck from "../../util/roleCheck"; +import Database from 'better-sqlite3'; +const db = new Database('./records/SERVER.db'); +db.pragma('journal_mode = WAL'); + import type { IChannel } from "../../type/Channel"; -export default async function updateChannel(userId:string, channelId:string, channelInfo:IChannel) -:Promise { +/** + * チャンネルの情報を更新する + * @param _userId 操作元のユーザーId + * @param _channelId 対象のチャンネルId + * @param _channelInfo 適用するチャンネル情報 + * @returns + */ +export default function updateChannel( + _userId: string, + _channelId: string, + _channelInfo: IChannel +):boolean { try { //チャンネル編集権限があるか調べて、なければfalse - const resultRoleCheck = await roleCheck(userId, "ChannelManage"); + const resultRoleCheck = roleCheck(_userId, "ChannelManage"); if (!resultRoleCheck) return false; - return new Promise((resolve) => { - //更新 - db.run( - ` - UPDATE CHANNELS SET - channelName=?, - description=?, - isPrivate=?, - speakableRole=? - WHERE channelId=? - `, - [ - channelInfo.channelName, - channelInfo.description, - channelInfo.isPrivate, - channelInfo.speakableRole.join(), - channelId - ], (err:Error) => { - if (err) { - console.log("updateChannel :: db : エラー->", err); - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + db.prepare( + ` + UPDATE CHANNELS SET + channelName=?, + description=?, + isPrivate=?, + speakableRole=? + WHERE channelId=? + ` + ).run( + _channelInfo.channelName, + _channelInfo.description, + _channelInfo.isPrivate?1:0, + _channelInfo.speakableRole.join(), + _channelId + ); + + return true; } catch(e) { diff --git a/src/actionHandler/File/calcFullFolderSize.ts b/src/actionHandler/File/calcFullFolderSize.ts index e32909a1..ea95ed93 100644 --- a/src/actionHandler/File/calcFullFolderSize.ts +++ b/src/actionHandler/File/calcFullFolderSize.ts @@ -1,15 +1,17 @@ import calcDirectorySize from "../../util/FIle/calcDirectorySize"; /** - * フォルダのサイズを取得 + * 指定のユーザーId用フォルダの総サイズを取得 + * @param _userId + * @returns */ -export default async function calcFullFolderSize( - userId: string, -):Promise { +export default function calcFullFolderSize( + _userId: string, +):number|null { try { //容量を計算する、できなかったらエラー - const folderSize = await calcDirectorySize(userId, ""); + const folderSize = calcDirectorySize(_userId, ""); if (folderSize === null) { return null; } diff --git a/src/actionHandler/File/createFolder.ts b/src/actionHandler/File/createFolder.ts index ae45ce92..cf27a192 100644 --- a/src/actionHandler/File/createFolder.ts +++ b/src/actionHandler/File/createFolder.ts @@ -1,7 +1,6 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); -import type { IFile, IFolder } from "../../type/File"; -import fetchFolders from "../../util/FIle/fetchFolders"; +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); /** * フォルダーを作成する @@ -9,11 +8,11 @@ import fetchFolders from "../../util/FIle/fetchFolders"; * @param folderName * @param directory */ -export default async function createFolder( - userId: string, - folderName: string, - directoryId: string = "" -):Promise { +export default function createFolder( + _userId: string, + _folderName: string, + _directoryId = "" +):boolean { try { //ファイルId生成 @@ -25,27 +24,16 @@ export default async function createFolder( return id; } - //ディレクトリデータを挿入 - return new Promise((resolve) => { - db.run( - ` - INSERT INTO FOLDERS ( - id, userId, name, positionedDirectoryId - ) VALUES (?, ?, ?, ?) - `, - [folderIdGenerated(), userId, folderName, directoryId], - (err:Error) => { - if (err) { - console.log("createFolder :: エラー->", err); - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + //フォルダデータをテーブルへ挿入 + db.prepare( + ` + INSERT INTO FOLDERS ( + id, userId, name, positionedDirectoryId + ) VALUES (?, ?, ?, ?) + ` + ).run(folderIdGenerated(), _userId, _folderName, _directoryId); + + return true; } catch(e) { diff --git a/src/actionHandler/File/deleteFile.ts b/src/actionHandler/File/deleteFile.ts index e101de61..d9e5f462 100644 --- a/src/actionHandler/File/deleteFile.ts +++ b/src/actionHandler/File/deleteFile.ts @@ -1,41 +1,40 @@ -import fs from "fs"; -import sqlite3 from "sqlite3"; +import fs from "node:fs"; import fetchFileInfo from "../../util/FIle/fetchFileInfo"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); -export default async function deleteFile( - userId: string, - fileId :string -):Promise { +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); + +/** + * ファイルを削除する + * @param userId + * @param fileId + * @returns + */ +export default function deleteFile( + _userId: string, + _fileId :string +):boolean { try { //ファイル情報を取得、無ければエラー - const fileInfo = await fetchFileInfo(fileId); + const fileInfo = fetchFileInfo(_fileId); if (fileInfo === null) return false; //ファイルを削除する - fs.unlink('./STORAGE/USERFILE/' + userId + '/' + fileInfo.actualName, (err) => { + fs.unlink(`./STORAGE/USERFILE/${_userId}/${fileInfo.actualName}`, (err) => { if (err) { console.log(err); return false; } }); - //ファイルインデックスから削除する - return new Promise((resolve) => { - db.run( - "DELETE FROM FILE" + userId + " WHERE id=?", - fileId, - (err) => { - if (err) { - resolve(false); - return; - } else { - resolve(true); - return; - } - }); - }); + //テーブルからもファイルデータを削除 + db.prepare( + `DELETE FROM FILE${_userId} WHERE id=?` + ).run(_fileId); + + return true; } catch(e) { diff --git a/src/actionHandler/File/deleteFolder.ts b/src/actionHandler/File/deleteFolder.ts index 95b083cc..ecdbedd1 100644 --- a/src/actionHandler/File/deleteFolder.ts +++ b/src/actionHandler/File/deleteFolder.ts @@ -1,6 +1,9 @@ -import fs from "fs"; -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); +import fs from "node:fs"; + +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); + import fetchFolders from "../../util/FIle/fetchFolders"; import fetchFileIndex from "./fetchFileIndex"; @@ -8,30 +11,30 @@ import type { IFolder } from "../../type/File"; /** * フォルダを削除する - * @param userId - * @param folderId + * @param _userId + * @param _folderId * @returns */ -export default async function deleteFolder( - userId: string, - folderId: string -) { +export default function deleteFolder( + _userId: string, + _folderId: string +):boolean { try { //削除するフォルダーに含まれるすべての下部フォルダId配列 - let folderIdArr:string[] = [folderId]; + let folderIdArr:string[] = [_folderId]; //下部フォルダId用配列の順番用変数 let index = 0; //探索結果に配列がある限り追加を続ける while (folderIdArr[index] !== undefined) { //その中のフォルダを取得 - const foldersFetched:IFolder[]|null = await fetchFolders(userId, folderIdArr[index]); + const foldersFetched:IFolder[]|null = fetchFolders(_userId, folderIdArr[index]); //もしフォルダ情報がとれたのなら探索結果配列へIdを追加 if (foldersFetched !== null) { - foldersFetched.forEach((folder:IFolder) => { + for (const folder of foldersFetched) { folderIdArr.push(folder.id); - }); + } //重複を省く folderIdArr = Array.from(new Set(folderIdArr)); } @@ -41,42 +44,27 @@ export default async function deleteFolder( } //フォルダId配列をループしそれぞれにあるファイルを全削除 - for (let folderId of folderIdArr) { + for (const folderId of folderIdArr) { //ファイルインデックス取得 - const fileIndex = await fetchFileIndex(userId, folderId); + const fileIndex = fetchFileIndex(_userId, folderId); //もしファイルが存在するなら削除 if (fileIndex !== null) { - for (let file of fileIndex) { + for (const file of fileIndex) { //ファイルを削除する - fs.unlink('./STORAGE/USERFILE/' + userId + '/' + file.name, (err) => { + fs.unlink(`./STORAGE/USERFILE/${_userId}/${file.actualName}`, (err) => { if (err) { console.log("deleteFolder :: ファイル削除 : このファイル削除ではエラー->", err); } }); //ファイルインデックスを削除 - db.run( - "DELETE FROM FILE" + userId + " WHERE id=?", - file.id, - (err) => { - if (err) { - console.log("deleteFolder :: DB(インデックス削除) : このファイルインデックス削除ではエラー->", err); - } - }); + db.prepare(`DELETE FROM FILE${_userId} WHERE id=?`).run(file.id); } } //ファイルインデックスを削除 - db.run( - "DELETE FROM FOLDERS WHERE id=?", - folderId, - (err) => { - if (err) { - console.log("deleteFolder :: DB(フォルダー削除) : このフォルダー削除ではエラー->", err); - } - }); - + db.prepare("DELETE FROM FOLDERS WHERE id=?").run(folderId); } return true; diff --git a/src/actionHandler/File/fetchFileIndex.ts b/src/actionHandler/File/fetchFileIndex.ts index 5e3f0f9b..26a1737f 100644 --- a/src/actionHandler/File/fetchFileIndex.ts +++ b/src/actionHandler/File/fetchFileIndex.ts @@ -1,36 +1,34 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); + import type { IFile } from "../../type/File"; -export default async function fetchFileIndex( - userId: string, - directory: string = "", - searchQuery: string = "" -):Promise { +/** + * 指定ユーザーのファイルインデックス取得 + * @param _userId + * @param _directory + * @param _searchQuery + * @returns + */ +export default function fetchFileIndex( + _userId: string, + _directory = "", + _searchQuery = "" +):IFile[]|null { try { - return new Promise((resolve) => { - db.all( - ` - SELECT * FROM FILE` + userId + ` - WHERE directory=? - AND - name LIKE '%` + searchQuery + `%' - `, - directory, - (err:Error, fileIndex:IFile[]) => { - if (err) { - console.log("fetchFileIndex :: db : エラー->", err); - resolve(null); - return; - } else { - //console.log("fetchFileIndex :: db : 結果->", fileIndex); - resolve(fileIndex); - return; - } - } - ); - }); + //ファイルインデックスを取得 + const FileIndex = db.prepare( + ` + SELECT * FROM FILE${_userId} + WHERE directory=? + AND + name LIKE '%${_searchQuery}%' + ` + ).all(_directory) as IFile[]; + + return FileIndex; } catch(e) { diff --git a/src/actionHandler/File/toggleFileIsPublic.ts b/src/actionHandler/File/toggleFileIsPublic.ts index 389338a4..b7b7608e 100644 --- a/src/actionHandler/File/toggleFileIsPublic.ts +++ b/src/actionHandler/File/toggleFileIsPublic.ts @@ -1,38 +1,33 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); + import fetchFileInfo from "../../util/FIle/fetchFileInfo"; /** * ファイルの公開設定をトグル + * @param _userId + * @param _fileId + * @returns */ -export default async function toggleFileIsPublic(userId:string, fileId:string) -:Promise { +export default function toggleFileIsPublic(_userId:string, _fileId:string) +:boolean { try { //ファイル情報を取得して無ければ停止する - const fileInfo = await fetchFileInfo(fileId); + const fileInfo = fetchFileInfo(_fileId); if (fileInfo === null) return false; - return new Promise((resolve) => { - db.run( - ` - UPDATE FILE` + userId + ` SET - isPublic=? - WHERE id=? - `, - [!fileInfo.isPublic, fileId], //反対にするだけ - (err:Error) => { - if (err) { - console.log("toggleFileIsPublic :: db : エラー->", err); - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + //ファイルの公開設定切り替えを記録 + db.prepare( + ` + UPDATE FILE${_userId} SET + isPublic=? + WHERE id=? + ` + ).run(!fileInfo.isPublic?1:0, _fileId); + + return true; } catch(e) { diff --git a/src/actionHandler/Message/deleteMessage.ts b/src/actionHandler/Message/deleteMessage.ts index 7d005861..3bbfb5a3 100644 --- a/src/actionHandler/Message/deleteMessage.ts +++ b/src/actionHandler/Message/deleteMessage.ts @@ -1,44 +1,42 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/MESSAGE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/MESSAGE.db'); +db.pragma('journal_mode = WAL'); + import calcRoleUser from "../Role/calcRoleUser"; import fetchMessage from "./fetchMessage"; -export default async function deleteMessage( - channelId: string, - messageId: string, - userIdBy: string, -):Promise { +/** + * メッセージを削除する + * @param _channelId + * @param _messageId + * @param _userIdBy 削除操作をしているユーザーのId + * @returns + */ +export default function deleteMessage( + _channelId: string, + _messageId: string, + _userIdBy: string, +):boolean { try { //削除するメッセージを取得 - const messageDeleting = await fetchMessage(channelId, messageId); + const messageDeleting = fetchMessage(_channelId, _messageId); if (messageDeleting === null) return false; //削除する人の権限レベル - const rolePower = await calcRoleUser(userIdBy); + const rolePower = calcRoleUser(_userIdBy); //削除される人の権限レベル - const rolePowerAgainst = await calcRoleUser(messageDeleting.userId); + const rolePowerAgainst = calcRoleUser(messageDeleting.userId); //レベル比較 if (rolePowerAgainst > rolePower) return false; - return new Promise((resolve) => { - //メッセージを削除 - db.run( - "DELETE FROM C" + channelId + " WHERE messageId=?", - messageId, - (err) => { - //結果に応じてbooleanで結果を返す - if (err) { - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + //メッセージを削除 + db.prepare( + `DELETE FROM C${_channelId} WHERE messageId=?` + ).run(_messageId); + + return true; } catch(e) { diff --git a/src/actionHandler/Message/editMessage.ts b/src/actionHandler/Message/editMessage.ts index b0ca4800..accd78ff 100644 --- a/src/actionHandler/Message/editMessage.ts +++ b/src/actionHandler/Message/editMessage.ts @@ -1,61 +1,54 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/MESSAGE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/MESSAGE.db'); +db.pragma('journal_mode = WAL'); + import fetchMessage from "./fetchMessage"; import type { IMessage } from "../../type/Message"; /** * メッセージの編集 - * @param channelId - * @param messageId - * @param userIdBy + * @param _channelId + * @param _messageId + * @param _userIdBy * @returns */ export default async function editMessage( - channelId: string, - messageId: string, - contentUpdating: string, - userIdBy: string, + _channelId: string, + _messageId: string, + _contentUpdating: string, + _userIdBy: string, ):Promise { try { //もし更新内容が空なら停止 - if (contentUpdating === "" || contentUpdating === null) return null; + if (_contentUpdating === "" || _contentUpdating === null) return null; //編集するメッセージを取得 - const messageEditing = await fetchMessage(channelId, messageId); + const messageEditing = fetchMessage(_channelId, _messageId); if (messageEditing === null) return null; //もし現在のテキストと編集内容が一緒なら停止 - if (messageEditing.content === contentUpdating) return null; + if (messageEditing.content === _contentUpdating) return null; //操作者とメッセ主が違うならエラーで停止 - if (messageEditing.userId !== userIdBy) return null; - - return new Promise((resolve) => { - db.run( - ` - UPDATE C` + channelId + ` SET - content=?, - isEdited=? - WHERE messageId='` + messageId + `' - `, - [contentUpdating, true], - (err:Error) => { - if (err) { - console.log("editMessage :: db : エラー->", err); - resolve(null); - return; - } else { - //取得したメッセデータも上書きして結果として渡す - messageEditing.content = contentUpdating; - messageEditing.isEdited = true; - resolve(messageEditing); - return; - } - } - ); - }); + if (messageEditing.userId !== _userIdBy) return null; + + //メッセージの編集をDBへ適用 + db.prepare( + ` + UPDATE C${_channelId} SET + content=?, + isEdited=? + WHERE messageId='${_messageId}' + ` + ).run(_contentUpdating, 1); + + //取得したメッセデータも上書きして結果として渡す + messageEditing.content = _contentUpdating; + messageEditing.isEdited = true; + + return messageEditing; } catch(e) { diff --git a/src/actionHandler/Message/fetchHistory.ts b/src/actionHandler/Message/fetchHistory.ts index 43696870..aae56839 100644 --- a/src/actionHandler/Message/fetchHistory.ts +++ b/src/actionHandler/Message/fetchHistory.ts @@ -1,46 +1,53 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/MESSAGE.db"); - -import { IMessage, IMessageBeforeParsing } from "../../type/Message"; - -export default async function fetchHistory( - channelId: string, - fetchingPosition: { +import Database from 'better-sqlite3'; +const db = new Database('./records/MESSAGE.db'); +db.pragma('journal_mode = WAL'); + +import type { IMessage, IMessageBeforeParsing } from "../../type/Message"; + +/** + * 履歴を取得する + * @param _channelId + * @param _fetchingPosition + * @returns + */ +export default function fetchHistory( + _channelId: string, + _fetchingPosition: { positionMessageId?: string positionMessageTime?: string includeThisPosition: boolean, fetchDirection: "older"|"newer" } -):Promise< +): { history: IMessage[], atTop: boolean, atEnd: boolean } | null -> { + { try { //履歴の取り込み数 - let historyLimit:number = 30; + let historyLimit = 30; //履歴を読み出し始める位置 - let positionIndex:number = 0; + let positionIndex = 0; //メッセージ位置の設定、指定がないなら0 if ( ( //Idの指定があるか? - fetchingPosition.positionMessageId !== "" && fetchingPosition.positionMessageId !== undefined + _fetchingPosition.positionMessageId !== "" && _fetchingPosition.positionMessageId !== undefined ) || ( //または時間の指定があるか? - fetchingPosition.positionMessageTime !== "" && fetchingPosition.positionMessageTime !== undefined + _fetchingPosition.positionMessageTime !== "" && _fetchingPosition.positionMessageTime !== undefined ) ) { //メッセージのインデックス番号を計算する - const positionTemp = await calcPositionOfMessage( - channelId, + const positionTemp = calcPositionOfMessage( + _channelId, { - messageId: fetchingPosition.positionMessageId, - time: fetchingPosition.positionMessageTime + messageId: _fetchingPosition.positionMessageId, + time: _fetchingPosition.positionMessageTime } ); @@ -48,14 +55,13 @@ export default async function fetchHistory( if (positionTemp === null) { //nullなら処理停止 return null; - } else { - //成功なら値を格納 - positionIndex = positionTemp; } + + positionIndex = positionTemp; //もし取得はじめの位置も履歴に含めるならpositionIndexをずらす - if (fetchingPosition.includeThisPosition) { - if (fetchingPosition.fetchDirection === "newer") { + if (_fetchingPosition.includeThisPosition) { + if (_fetchingPosition.fetchDirection === "newer") { positionIndex += 1; } else { positionIndex = @@ -65,30 +71,13 @@ export default async function fetchHistory( } //履歴の長さを取得 - const historyLength:number|null = await new Promise((resolve):number|null => { - db.all( - ` - SELECT COUNT(*) FROM C` + channelId + ` - `, - (err:Error, length:[{"COUNT(*)":number}]) => { - if (err) { - console.log("fetchHistory :: db(履歴の長さ取得) : エラー->", err); - resolve(null); - return; - } else { - resolve(length[0]['COUNT(*)']); - //console.log("fetchHistory :: db(historyLength) : historyLength->", length); - return; - } - } - ); - return null; - }); - //もし長さを取得できなかったのならエラーとして停止 - if (historyLength === null) return null; + const historyLengthRaw = db.prepare( + `SELECT COUNT(*) FROM C${_channelId}` + ).get() as {"COUNT(*)":number}; + const historyLength = historyLengthRaw["COUNT(*)"]; //履歴取得方向がnewerなら取得開始位置を30上にする(時系列的に古く) - if (fetchingPosition.fetchDirection === "newer") { + if (_fetchingPosition.fetchDirection === "newer") { //そもそも30ないなら0にする if (positionIndex - 30 < 0) { //履歴の取り込み数を開始位置にしてその分だけしかとらないようにする @@ -101,83 +90,73 @@ export default async function fetchHistory( } } - //履歴出力 - return await new Promise ((resolve) => { - db.all( - ` - SELECT * FROM C` + channelId + ` - ORDER BY time DESC - LIMIT ` + historyLimit + ` - OFFSET ` + positionIndex + ` - `, - (err:Error, history:IMessageBeforeParsing[]) => { - if (err) { - console.log("fetchHistory :: db(履歴取得) : エラー->", err); - resolve(null); - return; - } else { - //console.log("fetchHistory :: db : history->", history); - - //履歴の先頭あるいは終わりにいるかどうか用変数 - let atTop:boolean = false; - let atEnd:boolean = false; - //履歴の長さから取得開始位置を引いて30以内なら末端 - if (historyLength - positionIndex < 30) { - atTop = true; - } - //// ↓atEnd計算 //// - //新しい方に履歴を取得している場合 - if (fetchingPosition.fetchDirection === "newer") { - //取得開始位置が0なら最新 - if (positionIndex === 0) { - atEnd = true; - } - } else { //古い方を取っている場合 - //もし取得位置も含めてメッセージをとっていて0なら最新 - if ( - fetchingPosition.includeThisPosition - && - positionIndex === 0 - ) { - atEnd = true; - } - } - //// ↑atEnd計算ここまで //// - - //console.log("fetchHistory :: db : atTop?->", historyLength - positionIndex); - - //JSONでメッセージパースした用の配列 - let historyParsed:IMessage[] = []; - //パース処理 - for (let index in history) { - //リンクプレビューのJSONパース、nullかundefinedなら空JSONに - const linkDataParsed:IMessage["linkData"] = - (history[index].linkData!==null && history[index].linkData!==undefined) - ? - JSON.parse(history[index].linkData) - : - {}; + ///////////////////////////////////////////// + // ここから履歴の取得、位置計算 + ///////////////////////////////////////////// + + //履歴取得 + const history = db.prepare( + ` + SELECT * FROM C${_channelId} + ORDER BY time DESC + LIMIT ${historyLimit} + OFFSET ${positionIndex} + ` + ).all() as IMessageBeforeParsing[]; + + //履歴の先頭あるいは終わりにいるかどうか用変数 + let atTop = false; + let atEnd = false; + //履歴の長さから取得開始位置を引いて30以内なら末端 + if (historyLength - positionIndex < 30) { + atTop = true; + } - historyParsed.push({ - ...history[index], - isEdited: history[index].isEdited===1?true:false, - linkData: linkDataParsed, - fileId: history[index].fileId===''?[]:history[index].fileId.split(","), - reaction: JSON.parse(history[index].reaction) - }); - } + //// ↓最新履歴位置にいるか計算 //// + //新しい方に履歴を取得している場合 + if (_fetchingPosition.fetchDirection === "newer") { + //取得開始位置が0なら最新 + if (positionIndex === 0) { + atEnd = true; + } + } else { //古い方を取っている場合 + //もし取得位置も含めてメッセージをとっていて0なら最新 + if ( + _fetchingPosition.includeThisPosition + && + positionIndex === 0 + ) { + atEnd = true; + } + } + //// ↑最新履歴位置にいるか計算ここまで //// + + //JSONで履歴をパースした用の配列 + const historyParsed:IMessage[] = []; + //履歴のパース処理 + for (const index in history) { + //リンクプレビューのJSONパース、nullかundefinedなら空JSONに + const linkDataParsed:IMessage["linkData"] = + (history[index].linkData!==null && history[index].linkData!==undefined) + ? + JSON.parse(history[index].linkData) + : + {}; + + historyParsed.push({ + ...history[index], + isEdited: history[index].isEdited === 1, + linkData: linkDataParsed, + fileId: history[index].fileId===''?[]:history[index].fileId.split(","), + reaction: JSON.parse(history[index].reaction) + }); + } - //最後に返す結果 - resolve({ - history: historyParsed, - atTop: atTop, - atEnd: atEnd - }); - return; - } - } - ); - }); + return { + history: historyParsed, + atTop: atTop, + atEnd: atEnd + }; } catch(e) { @@ -187,73 +166,65 @@ export default async function fetchHistory( } } -//メッセージの位置を取得 -async function calcPositionOfMessage( - channelId:string, - messagePos: { +/** + * メッセージの位置を取得 + * @param _channelId + * @param _messagePos + * @returns + */ +function calcPositionOfMessage( + _channelId:string, + _messagePos: { messageId?: string, time?: string } -):Promise { - return await new Promise((resolve) => { - try { +):number|null { + try { - //位置計算に使うメッセージ情報 - let calcMode:"messageId"|"time" = "messageId"; - //引数に時間があるかで使う情報切り替え - if (messagePos.time !== undefined) { - calcMode = "time"; - } + //位置計算に使うメッセージ情報 + let calcMode:"messageId"|"time" = "messageId"; + //引数に時間があるかで使う情報切り替え + if (_messagePos.time !== undefined) { + calcMode = "time"; + } - //console.log("fetchHistory :: calcPositionOfMessage : calcMode->", calcMode); + //console.log("fetchHistory :: calcPositionOfMessage : calcMode->", calcMode); - //検索に使うSQL構文を選択(時間かメッセIdか) - const searchQuery = calcMode==="messageId" - ? - "messageId = '" + messagePos.messageId + "'" - : - "time = '" + messagePos.time + "'" + //検索に使うSQL構文を選択(時間かメッセIdか) + const searchQuery = calcMode==="messageId" + ? + `messageId = '${_messagePos.messageId}'` + : + `time = '${_messagePos.time}'` - //該当メッセージの位置取得 - db.all( - ` - WITH NumberedRows AS ( - SELECT - *, - ROW_NUMBER() OVER (ORDER BY time DESC) AS RowNum - FROM - C` + channelId + ` - ) + //RowNumとメッセのInterfaceを結合したものを作る + interface IRowNum {RowNum: number}; + interface IMessageBeforeParsingWithRowNum extends IMessageBeforeParsing, IRowNum {}; + + //履歴の位置を計算 + const dbResultCalcPosition = db.prepare( + ` + WITH NumberedRows AS ( SELECT - * + *, + ROW_NUMBER() OVER (ORDER BY time DESC) AS RowNum FROM - NumberedRows - WHERE - ${searchQuery}; - `, - (err:Error, messageWithIndex:any) => { - if (err) { - console.log("fetchHistory :: db(メッセ位置計算) : エラー->", err); - resolve(null); - return; - } else { - //console.log("fetchHistory :: calcPositionOfMessage(db) : data->", messageWithIndex); - //もし長さが0じゃないならそれを返す - if (messageWithIndex.length === 0) { - resolve(null); - } else { - resolve(messageWithIndex[0].RowNum); - } - return; - } - } - ); + C${_channelId} + ) + SELECT + * + FROM + NumberedRows + WHERE + ${searchQuery}; + ` + ).get() as IMessageBeforeParsingWithRowNum; - } catch(e) { + return dbResultCalcPosition.RowNum; - resolve(null); - return; + } catch(e) { - } - }); + return null; + + } } diff --git a/src/actionHandler/Message/fetchMessage.ts b/src/actionHandler/Message/fetchMessage.ts index 118ae954..17a0c8f6 100644 --- a/src/actionHandler/Message/fetchMessage.ts +++ b/src/actionHandler/Message/fetchMessage.ts @@ -1,47 +1,41 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/MESSAGE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/MESSAGE.db'); +db.pragma('journal_mode = WAL'); import type { IMessage, IMessageBeforeParsing } from "../../type/Message"; +/** + * メッセージを取得 + * @param _channelId + * @param _messageId + * @returns + */ export default function fetchMessage( - channelId: string, - messageId: string -):Promise|null { + _channelId: string, + _messageId: string +):IMessage|null { try { - return new Promise((resolve) => { - db.all( - ` - SELECT * FROM C` + channelId + ` - WHERE messageId='` + messageId + `' - `, - (err:Error, message:IMessageBeforeParsing[]) => { - if (err) { - console.log("fetchMessage :: db : エラー->", err); - resolve(null); - return; - } else { - //console.log("fetchMessage :: db : 結果->", message); - //取得メッセが空なら停止 - if (message.length === 0) { - resolve(null); - return; - } - - //生メッセージデータを扱える形にパースする - const messageParsed:IMessage = { - ...message[0], - isEdited: message[0].isEdited===1?true:false, - linkData: message[0].linkData!==undefined?JSON.parse(message[0].linkData):{}, - fileId: message[0].fileId!==''?message[0].fileId.split(","):[], //空なら''だけなのでこの条件 - reaction: message[0].reaction!==undefined?JSON.parse(message[0].reaction):{} - }; - resolve(messageParsed); - return; - } - } - ) - }); + //メッセージの取得 + const msg = db.prepare( + ` + SELECT * FROM C${_channelId} + WHERE messageId='${_messageId}' + ` + ).get() as IMessageBeforeParsing|undefined; + //undefinedならnull + if (msg === undefined) return null; + + //パースする + const msgParsed:IMessage = { + ...msg, + isEdited: msg.isEdited === 1, + linkData: msg.linkData!==undefined?JSON.parse(msg.linkData):{}, + fileId: msg.fileId!==''?msg.fileId.split(","):[], //空なら''だけなのでこの条件 + reaction: msg.reaction!==undefined?JSON.parse(msg.reaction):{} + } + + return msgParsed; } catch(e) { diff --git a/src/actionHandler/Message/getMessageReadTime.ts b/src/actionHandler/Message/getMessageReadTime.ts index d0ca15ba..68489f5f 100644 --- a/src/actionHandler/Message/getMessageReadTime.ts +++ b/src/actionHandler/Message/getMessageReadTime.ts @@ -1,37 +1,28 @@ -import sqlite3 from "sqlite3"; +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + import type { IMessageReadTime } from "../../type/Message"; -const db = new sqlite3.Database("./records/USER.db"); -//メッセージの最終既読時間をJSONで取得 -export default async function getMessageReadTime(userId:string) -:Promise { +/** + * メッセージの最終既読時間をJSONで取得 + * @param _userId + * @returns + */ +export default function getMessageReadTime(_userId:string) +:IMessageReadTime|null { try { - return new Promise((resolve) => { - db.all( - ` - SELECT messageReadTime FROM USERS_SAVES - WHERE userId='` + userId + `' - `, - (err:Error, messageReadTimeBeforeParsed:[{messageReadTime:string}]) => { - if (err) { - console.log("getMessageReadTime :: db : エラー->", err); - resolve(null); - return; - } else { - //console.log("getMessageReadTime :: db : data->", messageReadTimeBeforeParsed); - //パースして返す - const messageReadTime:IMessageReadTime = - JSON.parse( - messageReadTimeBeforeParsed[0]['messageReadTime'] - ); + //最新既読時間を取得する + const messageReadTimeBeforeParsed = db.prepare( + ` + SELECT messageReadTime FROM USERS_SAVES + WHERE userId=? + ` + ).get(_userId) as {messageReadTime:string}; - resolve(messageReadTime); - return; - } - } - ); - }); + //SQLからの生値をJSONへパースして返す + return JSON.parse(messageReadTimeBeforeParsed.messageReadTime); } catch(e) { diff --git a/src/actionHandler/Message/reactMessage.ts b/src/actionHandler/Message/reactMessage.ts index d9d50081..9bd6a343 100644 --- a/src/actionHandler/Message/reactMessage.ts +++ b/src/actionHandler/Message/reactMessage.ts @@ -1,58 +1,55 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/MESSAGE.db"); -import fetchMessage from "./fetchMessage"; +import Database from 'better-sqlite3'; +const db = new Database('./records/MESSAGE.db'); +db.pragma('journal_mode = WAL'); -import type { IMessage, IMessageBeforeParsing } from "../../type/Message"; +import fetchMessage from "./fetchMessage"; -export default async function reactMessage( - channelId: string, - messageId: string, - reactionName: string, - userId: string -):Promise { +/** + * メッセージへリアクションを追加 + * @param _channelId + * @param _messageId + * @param _reactionName + * @param _userId + * @returns + */ +export default function reactMessage( + _channelId: string, + _messageId: string, + _reactionName: string, + _userId: string +):boolean { try { //メッセージ情報を取得 - const message = await fetchMessage(channelId, messageId); + const message = fetchMessage(_channelId, _messageId); //もしメッセージがnullなら停止 if (message === null) return false; //もしそもそも対象のリアクションデータが空なら新しく作る - if (message.reaction[reactionName] === undefined) { + if (message.reaction[_reactionName] === undefined) { //空のを作る - message.reaction[reactionName] = {}; + message.reaction[_reactionName] = {}; //このユーザーID分のリアクション数を設定 - message.reaction[reactionName][userId] = 1; + message.reaction[_reactionName][_userId] = 1; } else { //このユーザーIDによるリアクション数を取得 - const reactionNumberByThisUser:number|undefined = message.reaction[reactionName][userId]; + const reactionNumberByThisUser:number|undefined = message.reaction[_reactionName][_userId]; //リアクションJSONへ追加(取得してundefinedなら0に) - message.reaction[reactionName][userId] = + message.reaction[_reactionName][_userId] = reactionNumberByThisUser===undefined ? 0 : reactionNumberByThisUser+1; } - //DBへの書き込み処理 - return new Promise((resolve) => { - db.run( - ` - UPDATE C` + channelId + ` SET - reaction=? - WHERE messageId='` + messageId + `' - `, - JSON.stringify(message.reaction), - (err:Error) => { - if (err) { - console.log("reactMessage :: db : エラー->", err); - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + //DBへ書き込む + db.prepare( + ` + UPDATE C${_channelId} SET + reaction=? + WHERE messageId='${_messageId}' + ` + ).run(JSON.stringify(message.reaction)); + + return true; } catch(e) { diff --git a/src/actionHandler/Message/saveMessage.ts b/src/actionHandler/Message/saveMessage.ts index a5aba1f2..c2e06997 100644 --- a/src/actionHandler/Message/saveMessage.ts +++ b/src/actionHandler/Message/saveMessage.ts @@ -1,42 +1,50 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/MESSAGE.db"); import { ServerInfo } from "../../db/InitServer"; import fetchUserInbox from "../User/fetchUserInbox"; +import Database from 'better-sqlite3'; +const db = new Database('./records/MESSAGE.db'); +db.pragma('journal_mode = WAL'); + import type { IMessage } from "../../type/Message"; -export default async function saveMessage( - userId: string, - message: { +/** + * メッセージデータを履歴テーブルへ書き込む + * @param _userId + * @param _message + * @returns + */ +export default function saveMessage( + _userId: string, + _message: { channelId: string, content: string, fileId: string[] } -):Promise< +): { messageResult: IMessage, userIdMentioning: string[] | null } | null -> { +{ try { //形成するメッセージデータ const messageData:IMessage = { messageId: "", - channelId: message.channelId, - userId: userId, + channelId: _message.channelId, + userId: _userId, isEdited: false, - content: message.content, + content: _message.content, linkData: {}, - fileId: message.fileId, + fileId: _message.fileId, time: "", reaction: {}, }; //もしメッセージ長がサーバー設定より長ければエラー - if (message.content.length > ServerInfo.config.MESSAGE.TxtMaxLength) { + if (_message.content.length > ServerInfo.config.MESSAGE.TxtMaxLength) { return null; } @@ -59,76 +67,43 @@ export default async function saveMessage( messageData.time = new Date().toJSON(); //メッセージIDを作成 - messageData.messageId = message.channelId + randId + timestampJoined; + messageData.messageId = _message.channelId + randId + timestampJoined; //メンションだった時用のInbox追加処理 - const userIdMentioning = await checkAndAddToInbox( - message.channelId, + const userIdMentioning = checkAndAddToInbox( + _message.channelId, messageData.messageId, - message.content + _message.content ); - //DB処理 - return new Promise((resolve) => { - - db.serialize(() => { - - //存在しなければそのチャンネル用のテーブルを作成する - db.run( - `create table if not exists C${message.channelId}( - messageId TEXT PRIMARY KEY, - channelId TEXT NOT NULL, - userId TEXT NOT NULL, - content TEXT NOT NULL, - isEdited BOOLEAN NOT NULL DEFAULT '0', - linkData TEXT DEFAULT '{}', - fileId TEXT NOT NULL, - time TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')), - reaction TEXT NOT NULL - )`); - - //メッセージを挿入 - db.run(` - INSERT INTO C${message.channelId} ( - messageId, - channelId, - userId, - time, - content, - fileId, - reaction - ) - VALUES (?, ?, ?, ?, ?, ?, ?) - `, - [ - messageData.messageId, - messageData.channelId, - messageData.userId, - messageData.time, - messageData.content, - messageData.fileId.join(","), - "{}" //最初は当然空 - ], - (err) => { - //エラーなら停止 - if (err) { - console.log("saveMessage :: db : エラー->", err); - resolve(null); - return; - } - - //ここでメッセージデータとメンションする人配列を返す - resolve({ - messageResult: messageData, - userIdMentioning: userIdMentioning - }); - return; - } - ); - - }); - - }); + //テーブルへデータ挿入 + db.prepare( + ` + INSERT INTO C${_message.channelId} ( + messageId, + channelId, + userId, + time, + content, + fileId, + reaction + ) + VALUES (?, ?, ?, ?, ?, ?, ?) + ` + ).run( + messageData.messageId, + messageData.channelId, + messageData.userId, + messageData.time, + messageData.content, + messageData.fileId.join(","), + "{}" //最初は当然空 + ); + + return { + messageResult: messageData, + userIdMentioning: userIdMentioning + }; } catch(e) { @@ -141,11 +116,11 @@ export default async function saveMessage( /** * メンションか返信なら対象のユーザーのInboxへ追加する */ -async function checkAndAddToInbox( +function checkAndAddToInbox( channelId: string, messageId: string, content: string -):Promise { +):string[]|null { //メンション用のRegex const MentionRegex:RegExp = /@<([0-9]*)>/g; //マッチ結果 @@ -162,7 +137,8 @@ async function checkAndAddToInbox( if (matchResult === null) return null; //db操作用 - const dbUser = new sqlite3.Database("./records/USER.db"); + const dbUser = new Database('./records/USER.db'); + dbUser.pragma('journal_mode = WAL'); //ユーザーがメンションされているなら対象の人のInboxに通知を追加 for (const targetUserId of userIdMentioning) { @@ -171,7 +147,7 @@ async function checkAndAddToInbox( //メンションクエリーから@<>を削除してユーザーIdを抽出 const userIdFormatted = targetUserId.slice(2).slice(0,-1); //この人のinboxを取り出す - const inboxOfTargetUser = await fetchUserInbox(userIdFormatted); + const inboxOfTargetUser = fetchUserInbox(userIdFormatted); if (inboxOfTargetUser === null) continue; //チャンネル用ホルダーが無ければ空配列を作成 @@ -182,19 +158,9 @@ async function checkAndAddToInbox( inboxOfTargetUser.mention[channelId].push(messageId); //Inboxデータを書き込み - dbUser.run( - ` - UPDATE USERS_SAVES SET inbox=? - WHERE userId=? - `, - [JSON.stringify(inboxOfTargetUser), userIdFormatted], - (err:Error) => { - if(err) { - console.log("savemessage :: checkAndAddToInbox>db : エラー->", err); - throw Error; - } - } - ); + dbUser.prepare( + "UPDATE USERS_SAVES SET inbox=? WHERE userId=?" + ).run(JSON.stringify(inboxOfTargetUser), userIdFormatted); //実際に通知を行うユーザーId配列へ追加 userIdMentioningProcessed.push(userIdFormatted); diff --git a/src/actionHandler/Message/setMessageReadTime.ts b/src/actionHandler/Message/setMessageReadTime.ts index abe72fb6..b5dfd23f 100644 --- a/src/actionHandler/Message/setMessageReadTime.ts +++ b/src/actionHandler/Message/setMessageReadTime.ts @@ -1,46 +1,42 @@ -import sqlite3 from "sqlite3"; -import type { IMessageReadTime } from "../../type/Message"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); import getMessageReadTime from "./getMessageReadTime"; -export default async function setMessageReadTime( - userId: string, - channelId: string, - messageTime: string -):Promise { +import type { IMessageReadTime } from "../../type/Message"; + +/** + * チャンネルの最新既読時間を設定 + * @param _userId + * @param _channelId + * @param _messageTime + * @returns + */ +export default function setMessageReadTime( + _userId: string, + _channelId: string, + _messageTime: string +):boolean { try { //メッセージ既読時間の読み取り - const messageReadTime:IMessageReadTime|null = await getMessageReadTime(userId); + const messageReadTime:IMessageReadTime|null = getMessageReadTime(_userId); //取得できなかったら失敗と返す if (messageReadTime===null) return false; //データを更新する - messageReadTime[channelId] = messageTime; - - //DBへの書き込み処理 - return new Promise((resolve) => { - db.run( - ` - UPDATE USERS_SAVES SET - messageReadTime=? - WHERE userId='` + userId + `' - `, - JSON.stringify(messageReadTime), - (err:Error) => { - if (err) { - console.log("setMessageReadTime :: db : エラー->", err); - resolve(false); - return; - } else { - //console.log("setMessageReadTime :: db : 成功 messageReadTime->", messageReadTime); - resolve(true); - return; - } - } - ); - }); + messageReadTime[_channelId] = _messageTime; + + db.prepare( + ` + UPDATE USERS_SAVES SET + messageReadTime=? + WHERE userId=? + ` + ).run(JSON.stringify(messageReadTime), _userId); + + return true; } catch(e) { diff --git a/src/actionHandler/Role/addRole.ts b/src/actionHandler/Role/addRole.ts index 5b64294e..9af70c4f 100644 --- a/src/actionHandler/Role/addRole.ts +++ b/src/actionHandler/Role/addRole.ts @@ -1,63 +1,58 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + import fetchUser from "../User/fetchUser"; import calcRoleData from "./calcRoleData"; import calcRoleUser from "./calcRoleUser"; import fetchRoleSingle from "./fetchRoleSingle"; -export default async function addRole( - sendersUserId: string, - targetUserId: string, - roleId: string -):Promise { +/** + * ユーザーにロールを付与 + * @param _sendersUserId 操作者のユーザーId + * @param _targetUserId ロールを付与するユーザーId + * @param _roleId 付与するロールId + * @returns + */ +export default function addRole( + _sendersUserId: string, + _targetUserId: string, + _roleId: string +): boolean { try { //ロールのレベルを計算 - const userRoleLevel = await calcRoleUser(sendersUserId); - const addingRoleLevel = await calcRoleData( - await fetchRoleSingle(roleId) + const userRoleLevel = calcRoleUser(_sendersUserId); + const addingRoleLevel = calcRoleData( + fetchRoleSingle(_roleId) ); - console.log("addRole :: 操作者レベル->", userRoleLevel); - console.log("addRole :: 付与するロールのレベル->", addingRoleLevel); + + //console.log("addRole :: 操作者レベル->", userRoleLevel); + //console.log("addRole :: 付与するロールのレベル->", addingRoleLevel); + //もし操作者のロールレベルが追加するロールレベルより低ければ停止 if (addingRoleLevel > userRoleLevel) { return false; } //ユーザー情報を取得してnullなら停止 - const userInfo = await fetchUser(targetUserId, null); + const userInfo = fetchUser(_targetUserId, null); if (userInfo === null) return false; //ロール配列抜き出し const roleArr = userInfo.role; //ロール配列にすでに入っているなら停止 - if (roleArr.includes(roleId)) return false; + if (roleArr.includes(_roleId)) return false; //配列へ追加 - roleArr.push(roleId); + roleArr.push(_roleId); + + //データを更新 + db.prepare( + "UPDATE USERS_INFO SET role=? WHERE userId=?" + ).run(roleArr.join(","), _targetUserId); - //DB処理 - return new Promise(async (resolve) => { - db.run( - "UPDATE USERS_INFO SET role=? WHERE userId=?", - [ - roleArr.join(","), //更新した参加チャンネル配列 - targetUserId //参加するユーザーID - ], - (err) => { - if (err) { - console.log("addRole :: db : エラー->", err); - //エラーなら失敗 - resolve(false); - return; - } else { - //無事なら成功 - resolve(true); - return; - } - } - ); - }); + return true; } catch(e) { diff --git a/src/actionHandler/Role/calcRoleData.ts b/src/actionHandler/Role/calcRoleData.ts index d463fbbc..2ad2c2f0 100644 --- a/src/actionHandler/Role/calcRoleData.ts +++ b/src/actionHandler/Role/calcRoleData.ts @@ -14,22 +14,33 @@ const roleLevel:{ }; */ -export default async function calcRoleData(roleDataChecking:IUserRole) -:Promise { +/** + * ロールデータのロールレベルを取得 + * @param roleDataChecking + * @returns + */ +export default function calcRoleData(roleDataChecking:IUserRole) +:number { try { //権限をそれぞれ調べてレベルを返す if (roleDataChecking.ServerManage) { return 5; - } else if (roleDataChecking.RoleManage) { + } + + if (roleDataChecking.RoleManage) { return 4; - } else if ( + } + + if ( roleDataChecking.ChannelManage || roleDataChecking.UserManage ) { return 3; - } else if ( + } + + if ( roleDataChecking.MessageDelete ) { return 2; diff --git a/src/actionHandler/Role/calcRoleUser.ts b/src/actionHandler/Role/calcRoleUser.ts index eb5ec683..97944811 100644 --- a/src/actionHandler/Role/calcRoleUser.ts +++ b/src/actionHandler/Role/calcRoleUser.ts @@ -16,23 +16,29 @@ const roleLevel:{ }; */ -export default async function calcRoleUser(userId:string) -:Promise { +export default function calcRoleUser(userId:string) +:number { try { //権限をそれぞれ調べてレベルを返す - if (await roleCheck(userId, "ServerManage")) { + if (roleCheck(userId, "ServerManage")) { return 5; - } else if (await roleCheck(userId, "RoleManage")) { + } + + if (roleCheck(userId, "RoleManage")) { return 4; - } else if ( - await roleCheck(userId, "ChannelManage") + } + + if ( + roleCheck(userId, "ChannelManage") || - await roleCheck(userId, "UserManage") + roleCheck(userId, "UserManage") ) { return 3; - } else if ( - await roleCheck(userId, "MessageDelete") + } + + if ( + roleCheck(userId, "MessageDelete") ) { return 2; } diff --git a/src/actionHandler/Role/createRole.ts b/src/actionHandler/Role/createRole.ts index 63d09d0d..7a4cbe43 100644 --- a/src/actionHandler/Role/createRole.ts +++ b/src/actionHandler/Role/createRole.ts @@ -1,10 +1,18 @@ -import sqlite3 from "sqlite3"; -import { IUserRole } from "../../type/User"; -const db = new sqlite3.Database("./records/ROLE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ROLE.db'); +db.pragma('journal_mode = WAL'); +import type { IUserRole, IUserRoleBeforeParsing } from "../../type/User"; + +/** + * ロールを作成する + * @param _userId + * @param _roleDataCreating + * @returns + */ export default async function createRole( - userId: string, - roleDataCreating: { + _userId: string, + _roleDataCreating: { name: string, color: string } @@ -18,33 +26,19 @@ export default async function createRole( return null; } - //書き込み結果を待ってそれを返す - return new Promise((resolve) => { - //テーブルへデータ挿入 - db.run(` - INSERT INTO ROLES ( - roleId, - name, - color - ) - VALUES (?, ?, ?) - `, - [ - roleIdNew, //生成したロールID - roleDataCreating.name, //名前 - roleDataCreating.color //ロールの色 - ], - (err) => { - if (err) { - resolve(null); - return; - } else { - resolve(roleIdNew); - return; - } - } - ); - }); + //ロールテーブルへ挿入 + db.prepare( + ` + INSERT INTO ROLES ( + roleId, + name, + color + ) + VALUES (?, ?, ?) + ` + ).run(roleIdNew, _roleDataCreating.name, _roleDataCreating.color); + + return roleIdNew; } catch(e) { @@ -54,9 +48,12 @@ export default async function createRole( } } -//チャンネルIDの空きを探す +/** + * ロールIDの空きを探す + * @returns string Idの空き + */ async function getNewRoleId():Promise { - let tryCount:number = 0; + let tryCount = 0; return new Promise((resolve) => { try { @@ -70,15 +67,10 @@ async function getNewRoleId():Promise { } //そのIDのロールデータを取得してみる - const datRole = await new Promise((resolve) => { - db.all( - "SELECT * FROM ROLES WHERE roleId=?", - roleIdGen, - (err, roleDat:IUserRole[]) => { - resolve(roleDat[0]); - } - ) - }); + const datRole = db.prepare( + "SELECT * FROM ROLES WHERE roleId=?" + ).get(roleIdGen) as IUserRoleBeforeParsing | undefined; + console.log("createRole :: getNewRoleId : datRole->", datRole); //取得したロールデータが無効ならループ停止してIDを返す diff --git a/src/actionHandler/Role/deleteRole.ts b/src/actionHandler/Role/deleteRole.ts index 96375208..e88b5318 100644 --- a/src/actionHandler/Role/deleteRole.ts +++ b/src/actionHandler/Role/deleteRole.ts @@ -1,20 +1,17 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/ROLE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ROLE.db'); +db.pragma('journal_mode = WAL'); -export default async function deleteRole(roleId:string) { +/** + * ロールを削除 + * @param roleId + * @returns + */ +export default function deleteRole(roleId:string) { try { - return new Promise((resolve) => { - db.run("DELETE FROM ROLES WHERE roleId=?", roleId, (err) => { - if (err) { - resolve(false); - return; - } else { - resolve(true); - return; - } - }); - }); + //ロールを削除 + db.prepare("DELETE FROM ROLES WHERE roleId=?").run(roleId); } catch(e) { diff --git a/src/actionHandler/Role/fetchRoleSingle.ts b/src/actionHandler/Role/fetchRoleSingle.ts index 16cc7081..5f9dc52f 100644 --- a/src/actionHandler/Role/fetchRoleSingle.ts +++ b/src/actionHandler/Role/fetchRoleSingle.ts @@ -1,5 +1,6 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/ROLE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ROLE.db'); +db.pragma('journal_mode = WAL'); import type { IUserRole, IUserRoleBeforeParsing } from "../../type/User"; @@ -16,42 +17,31 @@ const errorRoleHolder:IUserRole = { MessageAttatchFile: false }; -export default async function fetchRoleSingle(targetRoleId:string) -:Promise { +/** + * ロール情報を単体で取得する + * @param _targetRoleId + * @returns + */ +export default function fetchRoleSingle(_targetRoleId:string) +:IUserRole { try { - return new Promise((resolve) => { - //ロールデータをすべて取得 - db.all( - "SELECT * FROM ROLES WHERE roleId=?", - targetRoleId, - (err:Error, roleData:IUserRoleBeforeParsing[]) => { - if (err) { - resolve(errorRoleHolder); - return; - } else { - if (roleData.length === 0) { - resolve(errorRoleHolder); - return; - } - - //扱える形式へパース - const roleInfo:IUserRole = { - ...roleData[0], //名前、色、IDはパース不要 - ServerManage: roleData[0].ServerManage===1?true:false, - RoleManage: roleData[0].RoleManage===1?true:false, - ChannelManage: roleData[0].ChannelManage===1?true:false, - UserManage: roleData[0].UserManage===1?true:false, - MessageDelete: roleData[0].MessageDelete===1?true:false, - MessageAttatchFile: roleData[0].MessageAttatchFile===1?true:false - }; - //返す - resolve(roleInfo); - return; - } - } - ); - }); + //ロールを取得 + const role = db.prepare("SELECT * FROM ROLES WHERE roleId=?").get(_targetRoleId) as IUserRoleBeforeParsing|undefined; + if (role === undefined) return errorRoleHolder; + + //ロールをパース + const roleParsed:IUserRole = { + ...role, //名前、色、IDはパース不要 + ServerManage: role.ServerManage === 1, + RoleManage: role.RoleManage === 1, + ChannelManage: role.ChannelManage === 1, + UserManage: role.UserManage === 1, + MessageDelete: role.MessageDelete === 1, + MessageAttatchFile: role.MessageAttatchFile === 1 + }; + + return roleParsed; } catch(e) { diff --git a/src/actionHandler/Role/fetchRoles.ts b/src/actionHandler/Role/fetchRoles.ts index 1b6483b8..f361b0cf 100644 --- a/src/actionHandler/Role/fetchRoles.ts +++ b/src/actionHandler/Role/fetchRoles.ts @@ -1,39 +1,36 @@ -import sqlite3 from "sqlite3"; -import { IUserRole, IUserRoleBeforeParsing } from "../../type/User"; -const db = new sqlite3.Database("./records/ROLE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ROLE.db'); +db.pragma('journal_mode = WAL'); -export default async function fetchRoles():Promise { +import type { IUserRole, IUserRoleBeforeParsing } from "../../type/User"; + +/** + * すべてのロールを取得する + * @returns + */ +export default function fetchRoles():IUserRole[] | null { try { - return new Promise((resolve) => { - //ロールデータをすべて取得 - db.all("SELECT * FROM ROLES", (err:Error, roleData:IUserRoleBeforeParsing[]) => { - if (err) { - resolve(null); - return; - } else { - //変数パース用の配列変数 - let roleDataParsed:IUserRole[] = []; - //変数のパース処理 - for (let role of roleData) { - //配列プッシュ - roleDataParsed.push({ - roleId: role.roleId, - name: role.name, - color: role.color, - ServerManage: role.ServerManage===1?true:false, - RoleManage: role.RoleManage===1?true:false, - ChannelManage: role.ChannelManage===1?true:false, - UserManage: role.UserManage===1?true:false, - MessageDelete: role.MessageDelete===1?true:false, - MessageAttatchFile: role.MessageAttatchFile===1?true:false - }); - } - resolve(roleDataParsed); - return; - } + const roles = db.prepare("SELECT * FROM ROLES").all() as IUserRoleBeforeParsing[]; + + //変数パース用の配列変数 + const roleDataParsed:IUserRole[] = []; + + for (const role of roles) { + roleDataParsed.push({ + roleId: role.roleId, + name: role.name, + color: role.color, + ServerManage: role.ServerManage === 1, + RoleManage: role.RoleManage === 1, + ChannelManage: role.ChannelManage === 1, + UserManage: role.UserManage === 1, + MessageDelete: role.MessageDelete === 1, + MessageAttatchFile: role.MessageAttatchFile === 1 }); - }); + } + + return roleDataParsed; } catch(e) { diff --git a/src/actionHandler/Role/searchRole.ts b/src/actionHandler/Role/searchRole.ts index 518d154e..7d78b1cd 100644 --- a/src/actionHandler/Role/searchRole.ts +++ b/src/actionHandler/Role/searchRole.ts @@ -1,58 +1,58 @@ -import sqlite3 from "sqlite3"; -import { IUserRole, IUserRoleBeforeParsing } from "../../type/User"; -const db = new sqlite3.Database("./records/ROLE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ROLE.db'); +db.pragma('journal_mode = WAL'); -export default function searchRole(searchQuery:string, pageIndex:number) -:Promise< +import type { IUserRole, IUserRoleBeforeParsing } from "../../type/User"; + +/** + * ロール検索 + * @param _searchQuery + * @param _pageIndex + * @returns + */ +export default function searchRole(_searchQuery:string, _pageIndex:number) +: { role: IUserRole[], pageIndex: number } ->|null { + | + null +{ try { //ページ数に合わせて取得するデータをずらす - const itemOffset = (pageIndex - 1) * 30; - - return new Promise((resolve) => { - //ユーザー名でクエリが含まれるものを取得 - db.all( - ` - SELECT * FROM ROLES - WHERE name LIKE ? - LIMIT 30 - OFFSET ? - `, - ["%" + searchQuery + "%", itemOffset], - (err:Error, datRole:IUserRoleBeforeParsing[]) => { - if (err) { - console.log("searchRole :: db(エラー) ->", err); - resolve({role:[], pageIndex:1}); - } else { - //変数パース用の配列変数 - let roleDataParsed:IUserRole[] = []; - //変数のパース処理 - for (let role of datRole) { - //配列プッシュ - roleDataParsed.push({ - roleId: role.roleId, - name: role.name, - color: role.color, - ServerManage: role.ServerManage===1?true:false, - RoleManage: role.RoleManage===1?true:false, - ChannelManage: role.ChannelManage===1?true:false, - UserManage: role.UserManage===1?true:false, - MessageDelete: role.MessageDelete===1?true:false, - MessageAttatchFile: role.MessageAttatchFile===1?true:false - }); - } - //パースしたものを返す - resolve({role:roleDataParsed, pageIndex:pageIndex}); - return; - } - } - ); - }); + const itemOffset = (_pageIndex - 1) * 30; + + //ロール検索結果 + const roles = db.prepare( + ` + SELECT * FROM ROLES + WHERE name LIKE ? + LIMIT 30 + OFFSET ? + ` + ).all(`%${_searchQuery}%`, itemOffset) as IUserRoleBeforeParsing[]; + + //変数パース用の配列変数 + const roleDataParsed:IUserRole[] = []; + //変数のパース処理 + for (const role of roles) { + //配列プッシュ + roleDataParsed.push({ + roleId: role.roleId, + name: role.name, + color: role.color, + ServerManage: role.ServerManage === 1, + RoleManage: role.RoleManage === 1, + ChannelManage: role.ChannelManage === 1, + UserManage: role.UserManage === 1, + MessageDelete: role.MessageDelete === 1, + MessageAttatchFile: role.MessageAttatchFile === 1 + }); + } + + return {role:roleDataParsed, pageIndex:_pageIndex}; } catch(e) { diff --git a/src/actionHandler/Role/unlinkRole.ts b/src/actionHandler/Role/unlinkRole.ts index 738adf06..738dd1ef 100644 --- a/src/actionHandler/Role/unlinkRole.ts +++ b/src/actionHandler/Role/unlinkRole.ts @@ -1,21 +1,30 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + import fetchUser from "../User/fetchUser"; import calcRoleUser from "./calcRoleUser"; import calcRoleData from "./calcRoleData"; import fetchRoleSingle from "./fetchRoleSingle"; -export default async function unlinkRole( - sendersUserId: string, - targetUserId: string, - roleId: string -):Promise { +/** + * ユーザーから指定のロールを削除 + * @param _sendersUserId + * @param _targetUserId + * @param _roleId + * @returns + */ +export default function unlinkRole( + _sendersUserId: string, + _targetUserId: string, + _roleId: string +): boolean { try { //操作者と外すロールのレベル確認 - const sendersRoleLevel = await calcRoleUser(sendersUserId); - const unlinkingDataRoleLevel = await calcRoleData( - await fetchRoleSingle(roleId) + const sendersRoleLevel = calcRoleUser(_sendersUserId); + const unlinkingDataRoleLevel = calcRoleData( + fetchRoleSingle(_roleId) ); console.log("unlinkRole :: 操作者レベル->", sendersRoleLevel); console.log("unlinkRole :: 外すロールのレベル->", unlinkingDataRoleLevel); @@ -25,39 +34,23 @@ export default async function unlinkRole( } //ユーザー情報を取得してnullなら停止 - const userInfo = await fetchUser(targetUserId, null); + const userInfo = fetchUser(_targetUserId, null); if (userInfo === null) return false; //ロール配列抜き出し const roleArr = userInfo.role; //ロール配列にロールIDが無いなら停止 - if (!roleArr.includes(roleId)) return false; + if (!roleArr.includes(_roleId)) return false; //配列からロールID削除 - roleArr.splice(roleArr.indexOf(roleId), 1); + roleArr.splice(roleArr.indexOf(_roleId), 1); + + //ロール配列をDBへ適用 + db.prepare( + "UPDATE USERS_INFO SET role=? WHERE userId=?" + ).run(roleArr.join(","), _targetUserId); - //DB処理 - return new Promise(async (resolve) => { - db.run( - "UPDATE USERS_INFO SET role=? WHERE userId=?", - [ - roleArr.join(","), //更新した参加チャンネル配列 - targetUserId //参加するユーザーID - ], - (err) => { - if (err) { - console.log("unlinkRole :: db : エラー->", err); - //エラーなら失敗 - resolve(false); - return; - } else { - //無事なら成功 - resolve(true); - return; - } - } - ); - }); + return true; } catch(e) { diff --git a/src/actionHandler/Role/updateRole.ts b/src/actionHandler/Role/updateRole.ts index 1a962491..7cea84c3 100644 --- a/src/actionHandler/Role/updateRole.ts +++ b/src/actionHandler/Role/updateRole.ts @@ -1,19 +1,29 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/ROLE.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ROLE.db'); +db.pragma('journal_mode = WAL'); + import calcRoleUser from "./calcRoleUser"; import calcRoleData from "./calcRoleData"; import type { IUserRole } from "../../type/User"; -export default async function updateRole(userId:string, roleData:IUserRole) -:Promise { +/** + * ロールデータを更新する + * @param userId 操作者のユーザーId + * @param roleData 更新を適用するロールデータ(ロールIdはこの中から参照) + * @returns + */ +export default function updateRole(userId:string, roleData:IUserRole) +:boolean { try { //操作者と更新ロールデータ内容のレベル確認 - const sendersRoleLevel = await calcRoleUser(userId); - const updatingDataRoleLevel = await calcRoleData(roleData); - console.log("updateRole :: 操作者レベル->", sendersRoleLevel); - console.log("updateRole :: 更新するロールのレベル->", updatingDataRoleLevel); + const sendersRoleLevel = calcRoleUser(userId); + const updatingDataRoleLevel = calcRoleData(roleData); + + //console.log("updateRole :: 操作者レベル->", sendersRoleLevel); + //console.log("updateRole :: 更新するロールのレベル->", updatingDataRoleLevel); + //もし操作者のロールレベルが追加するロールレベルより低ければ停止 if (updatingDataRoleLevel > sendersRoleLevel) { return false; @@ -24,43 +34,32 @@ export default async function updateRole(userId:string, roleData:IUserRole) return false; } - return new Promise((resolve) => { - //更新 - db.run( - ` - UPDATE ROLES SET - name=?, - color=?, - ServerManage=?, - RoleManage=?, - ChannelManage=?, - UserManage=?, - MessageDelete=?, - MessageAttatchFile=? - WHERE roleId=? - `, - [ - roleData.name, //名前 - roleData.color, //色 - roleData.ServerManage, //権限いろいろ... - roleData.RoleManage, - roleData.ChannelManage, - roleData.UserManage, - roleData.MessageDelete, - roleData.MessageAttatchFile, - roleData.roleId //指定用のロールID - ], (err:Error) => { - if (err) { - console.log("updateRole :: db : エラー->", err); - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + db.prepare( + ` + UPDATE ROLES SET + name=?, + color=?, + ServerManage=?, + RoleManage=?, + ChannelManage=?, + UserManage=?, + MessageDelete=?, + MessageAttatchFile=? + WHERE roleId=? + ` + ).run( + roleData.name, //名前 + roleData.color, //色 + roleData.ServerManage?1:0, //権限いろいろ... + roleData.RoleManage?1:0, + roleData.ChannelManage?1:0, + roleData.UserManage?1:0, + roleData.MessageDelete?1:0, + roleData.MessageAttatchFile?1:0, + roleData.roleId //指定用のロールID + ); + + return true; } catch(e) { diff --git a/src/actionHandler/Server/updateServerConfig.ts b/src/actionHandler/Server/updateServerConfig.ts index 2407e86f..9c0c79f7 100644 --- a/src/actionHandler/Server/updateServerConfig.ts +++ b/src/actionHandler/Server/updateServerConfig.ts @@ -1,8 +1,8 @@ -import fs from "fs"; +import fs from "node:fs"; import { ServerInfo } from "../../db/InitServer"; import mergeDeeply from "../../util/mergeDeeply"; -import IServerInfo from "../../type/Server"; +import type IServerInfo from "../../type/Server"; //サーバー設定テンプレ const ServerInfoTemplate:IServerInfo = JSON.parse(fs.readFileSync('./src/db/defaultValues/ServerInfo.json', 'utf-8')); diff --git a/src/actionHandler/Server/updateServerInfo.ts b/src/actionHandler/Server/updateServerInfo.ts index 1a906ed4..f6d93e0a 100644 --- a/src/actionHandler/Server/updateServerInfo.ts +++ b/src/actionHandler/Server/updateServerInfo.ts @@ -1,4 +1,4 @@ -import fs from "fs"; +import fs from "node:fs"; import { ServerInfo } from "../../db/InitServer"; import mergeDeeply from "../../util/mergeDeeply"; diff --git a/src/actionHandler/User/banUser.ts b/src/actionHandler/User/banUser.ts index aad26acc..bff51ae4 100644 --- a/src/actionHandler/User/banUser.ts +++ b/src/actionHandler/User/banUser.ts @@ -1,35 +1,32 @@ -import sqlite3 from "sqlite3"; +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + import calcRoleUser from "../Role/calcRoleUser"; -const db = new sqlite3.Database("./records/USER.db"); -export default async function banUser(sendersUserId:string, targetUserId:string) -:Promise { +/** + * ユーザーをBANする + * @param sendersUserId 操作者のユーザーId + * @param targetUserId BANするユーザーId + * @returns + */ +export default function banUser(_sendersUserId:string, _targetUserId:string) +:boolean { try { //送信者と標的のロールレベルを取得 - const targetUserRoleLevel = await calcRoleUser(targetUserId); - const sendersUserRoleLevel = await calcRoleUser(sendersUserId); + const targetUserRoleLevel = calcRoleUser(_targetUserId); + const sendersUserRoleLevel = calcRoleUser(_sendersUserId); //もし標的者のレベルが送信者より上なら停止 if (targetUserRoleLevel > sendersUserRoleLevel) { return false; } - //書き込み - return new Promise((resolve) => { - db.run( - "UPDATE USERS_INFO SET banned=? WHERE userId=?", - [true, targetUserId], - (err) => { - if (err) { - console.log("banUser :: db : エラー->", err); - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + //DBへ記録 + db.prepare( + "UPDATE USERS_INFO SET banned=? WHERE userId=?" + ).run(1, _targetUserId); + + return true; } catch(e) { diff --git a/src/actionHandler/User/changeUserName.ts b/src/actionHandler/User/changeUserName.ts index b6932e83..89776772 100644 --- a/src/actionHandler/User/changeUserName.ts +++ b/src/actionHandler/User/changeUserName.ts @@ -1,17 +1,25 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); -export default async function changeUserName(userId:string, userName:string):Promise { - return new Promise((resolve) => { - //書き込み更新 - db.run("UPDATE USERS_INFO SET userName=? WHERE userId=?", [userName, userId], (err) => { - if (err) { - //エラーを投げる - throw err; - } else { - //成功と返す - resolve(true); - } - }); - }); +/** + * ユーザー名を変更する + * @param _userId + * @param _userName + * @returns + */ +export default function changeUserName(_userId:string, _userName:string):boolean { + try { + + //ユーザー名の変更を記録 + db.prepare("UPDATE USERS_INFO SET userName=? WHERE userId=?").run(_userName, _userId); + + return true; + + } catch(e) { + + console.log("changeUserName : エラー->", e); + return false; + + } } diff --git a/src/actionHandler/User/fetchUser.ts b/src/actionHandler/User/fetchUser.ts index 5fb477f2..440d4fbf 100644 --- a/src/actionHandler/User/fetchUser.ts +++ b/src/actionHandler/User/fetchUser.ts @@ -1,70 +1,53 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); -import { IUserInfo, IUserInfoBeforeParsing } from "../../type/User"; +import type { IUserInfo, IUserInfoBeforeParsing } from "../../type/User"; -export default async function fetchUser(userId:string|null, username:string|null) -:Promise { - return new Promise((resolve) => { - //ユーザーIDが引数に無かったらIDで検索する - if (userId === null) { - //ユーザーを名前で検索 - db.all("SELECT * FROM USERS_INFO WHERE userName = ?", [username], (err:Error, datUser:IUserInfoBeforeParsing[]) => { - if (err) { - console.log("fetchUser(userName) :: ERROR ->", err); - resolve(null); - } else { - //console.log("fetchUser(userName) :: 検索結果->", username, datUser); - //そもそも結果が無いならそう返す - if (datUser.length === 0) { - console.log("fetchUser(userName) :: ERROR -> データが空"); - resolve(null); - return; - } +/** + * ユーザー検索 + * @param _userId + * @param _username + * @returns + */ +export default function fetchUser(_userId:string|null, _username:string|null) +:IUserInfo|null { + try { - //console.log("fetchUser(userName) :: データ長->", datUser.length); + //ユーザーIDが引数に無かったらユーザー名で検索する + if (_userId === null) { + const userInfo = db.prepare( + "SELECT * FROM USERS_INFO WHERE userName = ?" + ).get(_username) as IUserInfo|undefined; - //ユーザー情報を取得して利用できるに整備 - let datUserParsed:IUserInfo = { - userId: datUser[0].userId, - userName: datUser[0].userName, - role: datUser[0].role.split(","), - channelJoined: datUser[0].channelJoined.split(","), - banned: datUser[0].banned===1?true:false - }; + if (userInfo !== undefined) { + return userInfo; + } - //ユーザー情報を返す - resolve(datUserParsed); - } - }); - } else { - //ユーザーをIDで検索 - db.all("SELECT * FROM USERS_INFO WHERE userId = ?", [userId], (err:Error, datUser:IUserInfoBeforeParsing[]) => { - if (err) { - console.log("fetchUser(userId) :: ERROR ->", err); - resolve(null); - } else { - //console.log("fetchUser(userId) :: 検索結果->", userId, datUser); - //そもそも結果が無いならそう返す - if (datUser.length === 0) { - console.log("fetchUser(userId) :: ERROR -> データが空"); - resolve(null); - return; - } + return null; + } - //ユーザー情報を取得して利用できるに整備 - let datUserParsed:IUserInfo = { - userId: datUser[0].userId, - userName: datUser[0].userName, - role: datUser[0].role.split(","), - channelJoined: datUser[0].channelJoined.split(","), - banned: datUser[0].banned===1?true:false - }; + const userInfo = db.prepare( + "SELECT * FROM USERS_INFO WHERE userId = ?" + ).get(_userId) as IUserInfoBeforeParsing|undefined; - //ユーザー情報を返す - resolve(datUserParsed); - } - }); + if (userInfo !== undefined) { + //パースして返す + const userInfoParsed:IUserInfo = { + ...userInfo, + channelJoined: userInfo.channelJoined.split(","), + role: userInfo.role.split(","), + banned: userInfo.banned===1 + }; + return userInfoParsed; } - }); + + return null; + + } catch(e) { + + console.log("fetchUser :: エラー->", e); + return null; + + } } diff --git a/src/actionHandler/User/fetchUserAll.ts b/src/actionHandler/User/fetchUserAll.ts index 6aacc657..4b158f10 100644 --- a/src/actionHandler/User/fetchUserAll.ts +++ b/src/actionHandler/User/fetchUserAll.ts @@ -1,77 +1,54 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); import type { IUserInfo, IUserInfoBeforeParsing } from "../../type/User"; -export default async function fetchUserAll(indexPage:number) -:Promise< - { - datUser: { - [key: string]: IUserInfo; - } | null; - countUser: number; - } | null ->{ +/** + * 複数ユーザーの情報を取得(30人単位) + * @param _indexPage + * @returns + */ +export default function fetchUserAll(_indexPage:number) +:{ + datUser: { + [key: string]: IUserInfo; + } | null; + countUser: number; +} | null +{ try { //ユーザーを取得し始める位置(1ページ30人) - const indexStarting:number = 30 * (indexPage - 1); + const indexStarting:number = 30 * (_indexPage - 1); - //ユーザーの数を数える - const countUser:number = await new Promise((resolve) => { - db.all("SELECT count(*) FROM USERS_INFO ", (err:Error, countUser:[{"count(*)":number}]) => { - if (err) { - console.log("fetchUser(userId) :: ERROR ->", err); - resolve(0); - } else { - //console.log("fetchUserAll :: countUser(db) : countUser[count(*)]->", countUser); - //ユーザーの数を返す - resolve(countUser[0]["count(*)"]); - } - }); - }); - //ユーザー情報取得、パース - const datUser:{ - [key: string]: IUserInfo - }|null = await new Promise((resolve) => { - db.all("SELECT * FROM USERS_INFO LIMIT 30 OFFSET ? ", indexStarting, (err:Error, datUser:IUserInfoBeforeParsing[]) => { - if (err) { - console.log("fetchUser(userId) :: ERROR ->", err); - resolve(null); - } else { - //console.log("fetchUserAll :: 検索結果->", userId, datUser); - //そもそも結果が無いならそう返す - if (datUser.length === 0) { - resolve(null); - return; - } - - //パースするユーザー情報を入れるJSON - const datUserParsed:{ - [key: string]: IUserInfo - } = {}; + //ユーザー数計算 + const usersNumRaw = db.prepare("SELECT count(*) FROM USERS_INFO").get() as {"count(*)":number}; + const userNum = usersNumRaw["count(*)"]; - //ユーザーの数だけループしてパース - for (let user of datUser) { - //JSONへ格納 - datUserParsed[user.userId] = { - userId: user.userId, - userName: user.userName, - role: user.role.split(","), - channelJoined: user.channelJoined.split(","), - banned: user.banned===1?true:false - }; - } + //ユーザー情報を取得 + const userInfos = db.prepare( + "SELECT * FROM USERS_INFO LIMIT 30 OFFSET ?" + ).all(indexStarting) as IUserInfoBeforeParsing[]; - //ユーザー情報を返す - resolve(datUserParsed); - return; - } - }); - }); - - //返す - return {datUser: datUser, countUser: countUser} + //パースしたユーザー情報を入れるJSON + const userInfosParsed:{ + [key: string]: IUserInfo + } = {}; + + //ユーザーの数だけループしてパース + for (const user of userInfos) { + //JSONへ格納 + userInfosParsed[user.userId] = { + userId: user.userId, + userName: user.userName, + role: user.role.split(","), + channelJoined: user.channelJoined.split(","), + banned: user.banned === 1 + }; + } + + return {datUser: userInfosParsed, countUser: userNum}; } catch(e) { diff --git a/src/actionHandler/User/fetchUserChannelOrder.ts b/src/actionHandler/User/fetchUserChannelOrder.ts index b721d051..85e8e4c6 100644 --- a/src/actionHandler/User/fetchUserChannelOrder.ts +++ b/src/actionHandler/User/fetchUserChannelOrder.ts @@ -1,24 +1,28 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); -export default async function fetchUserChannelOrder(userId: string) { +import type { IChannelOrder } from "../../type/Channel"; + +/** + * チャンネル順番データを取得 + * @param _userId + * @returns + */ +export default function fetchUserChannelOrder(_userId: string) +:IChannelOrder|null { try { - return new Promise((resolve) => { - db.all( - ` - SELECT channelOrder FROM USERS_SAVES - WHERE userId=? - `, - userId, - (err:Error, channelOrderData:[{channelOrder: string}]) => { - //console.log("fetchUserChannelOrder :: db : channelOrder->", channelOrderData); - //文字列をJSONにしてから返す - resolve(JSON.parse(channelOrderData[0].channelOrder)); - return; - } - ) - }); + const channelOrderData = db.prepare( + ` + SELECT channelOrder FROM USERS_SAVES + WHERE userId=? + ` + ).get(_userId) as {channelOrder: string}; + + const channelOrderParsed:IChannelOrder = JSON.parse(channelOrderData.channelOrder); + + return channelOrderParsed; } catch(e) { diff --git a/src/actionHandler/User/fetchUserConfig.ts b/src/actionHandler/User/fetchUserConfig.ts index 80916c39..1f38a3ab 100644 --- a/src/actionHandler/User/fetchUserConfig.ts +++ b/src/actionHandler/User/fetchUserConfig.ts @@ -1,42 +1,42 @@ -import fs from "fs"; -import sqlite3 from "sqlite3"; +import fs from "node:fs"; import mergeDeeply from "../../util/mergeDeeply"; -const db = new sqlite3.Database("./records/USER.db"); - -import { IUserConfig, IUserConfigBeforeParsing } from "../../type/User"; - -export default function fetchUserConfig(userId:string) -:Promise { - //ユーザー情報取得 - return new Promise((resolve) => { - try { - - //デフォルトの設定値取得 - const defaultConfigData:IUserConfig = JSON.parse(fs.readFileSync('./src/db/defaultValues/UserConfig.json', 'utf-8')); //サーバー情報のJSON読み込み - - //ユーザーをIDで検索 - db.all("SELECT * FROM USERS_CONFIG WHERE userId = ?", [userId], (err:Error, datConfig:IUserConfigBeforeParsing[]) => { - if (err) { - console.log("fetchUserConfig :: ERROR ->", err); - resolve(null); - } else { - //console.log("fetchUserConfig :: 検索結果->", userId, datConfig); - //DBでは設定の値がstringで保存されているためJSONへ - datConfig[0].channel = JSON.parse(datConfig[0].channel); - datConfig[0].notification = JSON.parse(datConfig[0].notification); - datConfig[0].sidebar = JSON.parse(datConfig[0].sidebar); - //設定データをデフォルトにマージする形で形成させる - const datConfigResult = mergeDeeply(defaultConfigData, datConfig[0]); - resolve(datConfigResult); - } - }); - - } catch(e) { - - console.log("fetchUserConfig :: fetchUserConfig : エラー->", e); - resolve(null); - return; - - } - }); + +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + +import type { IUserConfig, IUserConfigBeforeParsing } from "../../type/User"; + +/** + * ユーザーの設定データを取得 + * @param userId + * @returns + */ +export default function fetchUserConfig(_userId:string) +:IUserConfig|null { + try { + //デフォルトの設定値取得 + const defaultConfigData:IUserConfig = JSON.parse(fs.readFileSync('./src/db/defaultValues/UserConfig.json', 'utf-8')); //サーバー情報のJSON読み込み + + const userConfig = db.prepare("SELECT * FROM USERS_CONFIG WHERE userId = ?").get(_userId) as IUserConfigBeforeParsing | undefined; + if (userConfig === undefined) return null; + + //パースする + const userConfigParsed:IUserConfig = { + ...userConfig, + channel: JSON.parse(userConfig.channel), + notification: JSON.parse(userConfig.notification), + sidebar: JSON.parse(userConfig.sidebar), + userId: _userId + }; + + //設定データを初期設定へマージして返す + const configResult:IUserConfig = mergeDeeply(defaultConfigData, userConfigParsed); + return configResult; + + } catch(e) { + + return null; + + } } diff --git a/src/actionHandler/User/fetchUserInbox.ts b/src/actionHandler/User/fetchUserInbox.ts index 3f61fd99..69e4aca4 100644 --- a/src/actionHandler/User/fetchUserInbox.ts +++ b/src/actionHandler/User/fetchUserInbox.ts @@ -1,31 +1,26 @@ -import sqlite3 from "sqlite3"; -import { IUserInbox } from "../../type/User"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); -export default async function fetchUserInbox(userId: string):Promise { +import type { IUserInbox } from "../../type/User"; + +/** + * ユーザーのInbox(通知)を取得 + * @param _userId + * @returns + */ +export default function fetchUserInbox(_userId: string):IUserInbox|null { try { - return new Promise((resolve) => { - db.all( - ` - SELECT inbox FROM USERS_SAVES - WHERE userId=? - `, - userId, - (err:Error, inboxData:[{inbox: string}]) => { - if (err) { - console.log("fetchUserInbox :: エラー->", err); - resolve(null); - return; - } else { - //console.log("fetchUserChannelOrder :: db : channelOrder->", channelOrderData); - //文字列をJSONにしてから返す - resolve(JSON.parse(inboxData[0].inbox)); - return; - } - } - ) - }); + //Inboxのデータを取得(この時点ではString) + const userInbox = db.prepare( + "SELECT inbox FROM USERS_SAVES WHERE userId=?" + ).get(_userId) as {inbox: string}; + + //Inboxをパース + const userInboxParsed:IUserInbox = JSON.parse(userInbox.inbox); + + return userInboxParsed; } catch(e) { diff --git a/src/actionHandler/User/pardonUser.ts b/src/actionHandler/User/pardonUser.ts index f508916f..7ef696d6 100644 --- a/src/actionHandler/User/pardonUser.ts +++ b/src/actionHandler/User/pardonUser.ts @@ -1,29 +1,29 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); -export default async function pardonUser(sendersUserId:string, targetUserId:string) -:Promise { +import roleCheck from "../../util/roleCheck"; + +/** + * ユーザーのBAN解除 + * @param _sendersUserId + * @param _targetUserId + * @returns + */ +export default function pardonUser(_sendersUserId:string, _targetUserId:string) +:boolean { try { - - // ToDo :: 権限レベルの確認 - - //書き込み - return new Promise((resolve) => { - db.run( - "UPDATE USERS_INFO SET banned=? WHERE userId=?", - [false, targetUserId], - (err) => { - if (err) { - console.log("pardonUser :: db : エラー->", err); - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + + //権限を確認 + const canPardon = roleCheck(_sendersUserId, "UserManage"); + if (!canPardon) return false; + + //DBへ記録 + db.prepare( + "UPDATE USERS_INFO SET banned=? WHERE userId=?" + ).run(0, _targetUserId); + + return true; } catch(e) { diff --git a/src/actionHandler/User/removeFromUserInbox.ts b/src/actionHandler/User/removeFromUserInbox.ts index 6adea3f2..62abe9b2 100644 --- a/src/actionHandler/User/removeFromUserInbox.ts +++ b/src/actionHandler/User/removeFromUserInbox.ts @@ -1,51 +1,47 @@ -import sqlite3 from "sqlite3"; +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + import fetchUserInbox from "./fetchUserInbox"; -const db = new sqlite3.Database("./records/USER.db"); - -export default async function removeFromUserInbox( - userId: string, - inboxCategory: "mention"|"event", - channelId: string, - itemId: string -):Promise { + +/** + * Inboxから通知イベントを削除 + * @param userId + * @param inboxCategory + * @param channelId + * @param itemId + * @returns + */ +export default function removeFromUserInbox( + _userId: string, + _inboxCategory: "mention"|"event", + _channelId: string, + _itemId: string +):boolean { try { //このユーザーのInbox取得 - const inboxEditing = await fetchUserInbox(userId); + const inboxEditing = fetchUserInbox(_userId); if (!inboxEditing) { return false; }; //指定の項目Idの場所取得 - const indexOfItemId = inboxEditing[inboxCategory][channelId].indexOf(itemId); + const indexOfItemId = inboxEditing[_inboxCategory][_channelId].indexOf(_itemId); //消したい項目Idが無ければエラーとして返す if (indexOfItemId === -1) { return false; } //指定のIdの項目を削除 - inboxEditing[inboxCategory][channelId].splice(indexOfItemId, 1); - - return new Promise((resolve) => { - db.run( - ` - UPDATE USERS_SAVES SET inbox=? - WHERE userId=? - `, - [JSON.stringify(inboxEditing), userId], - (err:Error, inboxData:[{inbox: string}]) => { - if (err) { - console.log("removeFromUserInbox :: エラー->", err); - resolve(false); - return; - } else { - //console.log("removeFromUserInbox :: db : channelOrder->", channelOrderData); - resolve(true); - return; - } - } - ) - }); + inboxEditing[_inboxCategory][_channelId].splice(indexOfItemId, 1); + + //DBへ記録 + db.prepare( + "UPDATE USERS_SAVES SET inbox=? WHERE userId=?" + ).run(JSON.stringify(inboxEditing), _userId); + + return true; } catch(e) { diff --git a/src/actionHandler/User/saveUserChannelOrder.ts b/src/actionHandler/User/saveUserChannelOrder.ts index ebb0ba1a..a9832add 100644 --- a/src/actionHandler/User/saveUserChannelOrder.ts +++ b/src/actionHandler/User/saveUserChannelOrder.ts @@ -1,40 +1,30 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); import type { IChannelOrder } from "../../type/Channel"; -export default async function saveUserChannelOrder(userId:string, channelOrder:IChannelOrder) -:Promise { - return new Promise((resolve) => { - try { +/** + * チャンネルの順番データを保存する + * @param userId + * @param channelOrder + * @returns + */ +export default function saveUserChannelOrder(userId:string, channelOrder:IChannelOrder) +:boolean { + try { - //設定データを書き込み更新 - db.run( - ` - UPDATE USERS_SAVES SET channelOrder=? - WHERE userId=? - ` - , - [JSON.stringify(channelOrder), userId], - (err) => { - if (err) { - console.log("saveUserChannelOrder :: エラー->", err); - //失敗と返す - resolve(false); - return; - } else { - //成功と返す - resolve(true); - return; - } - }); - - } catch(e) { + //DBへ記録 + db.prepare( + "UPDATE USERS_SAVES SET channelOrder=? WHERE userId=?" + ).run(JSON.stringify(channelOrder), userId); - console.log("saveUserChannelOrder :: エラー->", e); - resolve(false); - return; + return true; - } - }); + } catch(e) { + + console.log("saveUserChannelOrder :: エラー->", e); + return false; + + } } \ No newline at end of file diff --git a/src/actionHandler/User/saveUserConfig.ts b/src/actionHandler/User/saveUserConfig.ts index 17e1cb7c..10d4ed81 100644 --- a/src/actionHandler/User/saveUserConfig.ts +++ b/src/actionHandler/User/saveUserConfig.ts @@ -1,42 +1,39 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); import type { IUserConfig } from "../../type/User"; -export default async function saveUserConfig(userId:string, datConfig:IUserConfig):Promise { - return new Promise((resolve) => { - try { +/** + * ユーザーの設定を保存する + * @param userId + * @param datConfig + * @returns + */ +export default function saveUserConfig(_userId:string, _datConfig:IUserConfig):boolean { + try { - //SQLの実行文 - const sqlContext = "UPDATE USERS_CONFIG SET notification=?, theme=?, channel=?, sidebar=? WHERE userId=?"; + //設定をDBへ記録 + db.prepare( + ` + UPDATE USERS_CONFIG SET + notification=?, theme=?, channel=?, sidebar=? + WHERE userId=? + ` + ).run( + JSON.stringify(_datConfig.notification), + _datConfig.theme, + JSON.stringify(_datConfig.channel), + JSON.stringify(_datConfig.sidebar), + _userId //書き込み先のユーザーID + ); - //設定データを書き込み更新 - db.run(sqlContext, - [ - JSON.stringify(datConfig.notification), - datConfig.theme, - JSON.stringify(datConfig.channel), - JSON.stringify(datConfig.sidebar), - userId //書き込み先のユーザーID - ], - (err) => { - if (err) { - //失敗と返す - resolve(false); - return; - } else { - //成功と返す - resolve(true); - return; - } - }); - - } catch(e) { + return true; + + } catch(e) { - console.log("saveUserConfig :: エラー->", e); - resolve(false); - return; + console.log("saveUserConfig :: エラー->", e); + return false; - } - }); + } } diff --git a/src/actionHandler/User/searchUser.ts b/src/actionHandler/User/searchUser.ts index 171b0515..6855ee09 100644 --- a/src/actionHandler/User/searchUser.ts +++ b/src/actionHandler/User/searchUser.ts @@ -1,55 +1,62 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); -import { IUserInfo } from "../../type/User"; +import type { IUserInfo, IUserInfoBeforeParsing } from "../../type/User"; + +/** + * ユーザーを検索する + * @param _userName + * @param _rule + * @param _channelId + * @returns + */ +export default function searchUser( + _userName: string, + _rule: "FULL"|"PARTIAL", + _channelId?: string +):IUserInfo[] { + try { -export default async function searchUser( - userName: string, - rule: "FULL"|"PARTIAL", - channelId?: string -):Promise { - return new Promise((resolve) => { //チャンネルIdの指定があるかどうかでSQL文へ追加する文構成 - const optionChannel = - channelId!==undefined + const stmtOptionChannel = + _channelId!==undefined ? - " AND channelJoined LIKE '%" + channelId + "%'" + ` AND channelJoined LIKE '%${_channelId}%'` : ""; //検索用クエリー const searchQuery = - rule==='PARTIAL' + _rule==='PARTIAL' ? - "%" + userName + "%" //部分検索 + `%${_userName}%` //部分検索 : - userName; //完全検索 - - console.log("searchUser :: sql文 ->", - ` - SELECT * FROM USERS_INFO - WHERE userName LIKE - ` + searchQuery + optionChannel - ); - - //ユーザー名でクエリが含まれるものを取得 - db.all( - ` - SELECT * FROM USERS_INFO - WHERE userName LIKE ? - ` + optionChannel, - [searchQuery], - (err:Error, datUser:IUserInfo[]) => { - if (err) { - console.log("searchUser :: ERROR ->", err); - resolve([]); - } else { - //console.log("searchUser :: 検索結果->", userName, datUser); - resolve(datUser); - } - } - ); - - }); + _userName; //完全検索 + + const users = db.prepare( + `SELECT * FROM USERS_INFO WHERE userName LIKE ? ${stmtOptionChannel}` + ).all(searchQuery) as IUserInfoBeforeParsing[]; + + //パースしたユーザー情報配列 + const usersParsed:IUserInfo[] = [] + //パース処理 + for (const user of users) { + usersParsed.push({ + ...user, + channelJoined: user.channelJoined.split(","), + role: user.role.split(","), + banned: user.banned===1 + }) + } + + return usersParsed; + + } catch(e) { + + console.log("searchUser :: エラー->", e); + return []; + + } } diff --git a/src/actionHandler/auth/authLogin.ts b/src/actionHandler/auth/authLogin.ts index bc0ad679..c87f94f7 100644 --- a/src/actionHandler/auth/authLogin.ts +++ b/src/actionHandler/auth/authLogin.ts @@ -1,50 +1,46 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); import fetchUser from "../User/fetchUser"; -import { IUserInfo, IUserPassword } from "../../type/User"; +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); -export default async function authLogin(username:string, password:string) -:Promise<{authResult:boolean, UserInfo:IUserInfo|null, sessionId:string|null}> { +import type { IUserInfo, IUserPassword } from "../../type/User"; + +/** + * パスワード認証を行う + * @param _username + * @param _password + * @returns + */ +export default function authLogin(_username:string, _password:string) +:{authResult:boolean, UserInfo:IUserInfo|null, sessionId:string|null} { try { //ユーザー情報取得 - const RESULT = await fetchUser(null, username); + const RESULT = fetchUser(null, _username); //console.log("authLogin :: authLogin : RESULT ->", RESULT); //そもそもユーザーが見つからないなら失敗として返す if (RESULT === null) return {authResult:false, UserInfo:null, sessionId:null}; - //パスワードを比較して結果保存 - const authResult:boolean = await new Promise(async (resolve) => { - db.all("SELECT * FROM USERS_PASSWORD WHERE userId = ?", [RESULT.userId], (err:Error, datUser:IUserPassword[]) => { - if (err) { - console.log("authLogin :: authLogin(db) : ERROR ->", err); - resolve(false); - } else { - //console.log("authLogin :: authLogin(db) : 検索結果->", datUser); - //パスワードが合っているならtrueに - if (datUser[0].password === password) { - //console.log("authLogin :: authLogin(db) : パスワード合ってるね") - resolve(true); - } else { - //console.log("authLogin :: authLogin(db) : パスワード違う"); - resolve(false); - } - } - }); - }); + //パスワードデータを取得 + const passwordData = db.prepare( + "SELECT * FROM USERS_PASSWORD WHERE userId=?" + ).get(RESULT.userId) as IUserPassword|undefined; + //undefinedなら停止 + if (passwordData === undefined) return {authResult:false, UserInfo:null, sessionId:null}; + + //パスワード比較 + const authResult = passwordData.password === _password; //違うなら失敗結果を返す if (authResult === false) return {authResult:false, UserInfo:null, sessionId:null}; //セッション情報を作成してDBへ挿入 const sessionIdGen = generateSessionId(); - db.run("insert into USERS_SESSION(userId, sessionId, sessionName) values(?,?,?)", - RESULT.userId, - sessionIdGen, - "ログイン" - ); + db.prepare( + "INSERT INTO USERS_SESSION(userId, sessionId, sessionName) values(?,?,?)" + ).run(RESULT.userId, sessionIdGen, "ログイン"); return {authResult:true, UserInfo:RESULT, sessionId:sessionIdGen}; diff --git a/src/actionHandler/auth/authRegister.ts b/src/actionHandler/auth/authRegister.ts index 9989cac7..97af69d8 100644 --- a/src/actionHandler/auth/authRegister.ts +++ b/src/actionHandler/auth/authRegister.ts @@ -1,11 +1,13 @@ -import fs from "fs"; -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import fs from "node:fs"; import fetchUser from "../User/fetchUser"; import { ServerInfo } from "../../db/InitServer"; -import { IUserConfig, IUserInfo } from "../../type/User"; -import IServerInfo from "../../type/Server"; +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + +import type { IUserConfig, IUserInfo } from "../../type/User"; +import type IServerInfo from "../../type/Server"; export default async function authRegister(username:string, inviteCode:string|null) :Promise<{userInfo:IUserInfo, password:string}|"ERROR_WRONGINVITECODE"|"ERROR_DB_THING"> { @@ -21,10 +23,10 @@ export default async function authRegister(username:string, inviteCode:string|nu //一番最初のユーザーを登録するのかどうか //最後に返すロールの内容用 - let isFirstUser:boolean = false; + let isFirstUser = false; //ユーザー名の空きを確認 - if ((await fetchUser(null, username)) !== null) throw Error; + if ((fetchUser(null, username)) !== null) throw Error; //空いているユーザーIDを見つける const userIdGen = await getNewUserId(); @@ -37,56 +39,53 @@ export default async function authRegister(username:string, inviteCode:string|nu //サーバーの設定ファイル読み取り const ServerConfig:IServerInfo = JSON.parse(fs.readFileSync("./records/server.json", "utf-8")); - //一番最初のユーザーかどうかを調べてそうならHostロールを付与して登録 - db.all("SELECT COUNT(*) FROM USERS_INFO", (err:Error, num:{"COUNT(*)":number}[]) => { - if (err) { - console.log("authRegister :: db : エラー->", err); - } else { - console.log("authRegister :: db : num->", num, typeof(num[0]["COUNT(*)"]), (num[0]["COUNT(*)"] === 0)); - //最初のユーザーだからHostロールを付与 - if (num[0]["COUNT(*)"] === 0) { - //ユーザー情報をDBへ作成 - db.run("insert into USERS_INFO values (?,?,?,?,?)", - userIdGen, - username, - "HOST", - "0001", - false - ); - //最初のユーザーであることを設定 - isFirstUser = true; - } else { //ユーザーがいたからMember - db.run("insert into USERS_INFO values (?,?,?,?,?)", - userIdGen, - username, - "MEMBER", - ServerConfig.config.CHANNEL.defaultJoinOnRegister.join(","), //サーバー設定のデフォルト参加チャンネル - false - ); - } - } - }); + const count = db.prepare("SELECT COUNT(*) FROM USERS_INFO").get() as {"COUNT(*)":number}; + console.log("authRegister :: カウント->", count); + + //ユーザー数が0ならHOSTアカウントを作る、1以上ならMemberで普通に作る + if (count["COUNT(*)"] === 0) { + db.prepare( + "insert into USERS_INFO values (?,?,?,?,?)" + ).run(userIdGen, username, "HOST", "0001", 0); + + //一人目のユーザーであることを記憶しておく + isFirstUser = true; + } else { + db.prepare( + "insert into USERS_INFO values (?,?,?,?,?)" + ).run( + userIdGen, + username, + "Member", + ServerConfig.config.CHANNEL.defaultJoinOnRegister.join(","), //デフォで参加するチャンネル + 0 + ); + } //生成したパスワードを記録 - db.run("insert into USERS_PASSWORD values (?,?)", userIdGen, passwordGenerated); + db.prepare( + "INSERT INTO USERS_PASSWORD values (?,?)" + ).run(userIdGen, passwordGenerated); //デフォルトのユーザー設定のJSON読み込み const defaultConfigData:IUserConfig = JSON.parse( fs.readFileSync('./src/db/defaultValues/UserConfig.json', 'utf-8') ); //デフォルトの設定の値をDBへ挿入 - db.run("INSERT INTO USERS_CONFIG (userId, notification, theme, channel, sidebar) values (?,?,?,?,?)", + db.prepare( + "INSERT INTO USERS_CONFIG (userId, notification, theme, channel, sidebar) values (?,?,?,?,?)" + ).run( userIdGen, JSON.stringify(defaultConfigData.notification), defaultConfigData.theme, JSON.stringify(defaultConfigData.channel), - JSON.stringify(defaultConfigData.sidebar), + JSON.stringify(defaultConfigData.sidebar) ); //デフォルトのユーザーデータ用テーブルのデータを作成 - db.run("INSERT INTO USERS_SAVES (userId) values (?)", - userIdGen - ); + db.prepare( + "INSERT INTO USERS_SAVES (userId) values (?)" + ).run(userIdGen); //console.log("authRegister :: アカウント作成したよ ->", userIdGen, passwordGenerated); @@ -111,7 +110,7 @@ export default async function authRegister(username:string, inviteCode:string|nu //ユーザーIDの空きを探す async function getNewUserId():Promise { - let tryCount:number = 0; + let tryCount = 0; return new Promise((resolve) => { try { diff --git a/src/actionHandler/auth/changePassword.ts b/src/actionHandler/auth/changePassword.ts index 1e52199e..b9596549 100644 --- a/src/actionHandler/auth/changePassword.ts +++ b/src/actionHandler/auth/changePassword.ts @@ -1,68 +1,54 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); -import fetchUser from "../User/fetchUser"; +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); -import { IUserInfo, IUserPassword } from "../../type/User"; +import type { IUserPassword } from "../../type/User"; -export default async function changePassword( - userId:string, currentPasword:string, newPassword:string -):Promise { - return new Promise(async (resolve) => { - try { +export default function changePassword( + _userId:string, _currentPasword:string, _newPassword:string +):boolean { + try { - //認証結果保存用 - let authResult:boolean = false; + //認証結果保存用 + let authResult = false; - //データ検索してパスワードを比較 - authResult = await checkPassword(userId, currentPasword); + //データ検索してパスワードを比較 + authResult = checkPassword(_userId, _currentPasword); - //console.log("changePassword :: authResult->", authResult); + //console.log("changePassword :: authResult->", authResult); - //認証できたならパスワード変更 - if (authResult) { - //パスワードを変更 - db.run("UPDATE USERS_PASSWORD SET password=? WHERE userId=?", [newPassword, userId], (err) => { - if (err) { - //エラーを投げる - throw err; - } else { - //成功と返す - resolve(true); - return; - } - }); - } else { //失敗ならそう返す - resolve(false); - return; - } + //認証できたならパスワード変更 + if (authResult) { + db.prepare( + "UPDATE USERS_PASSWORD SET password=? WHERE userId=?" + ).run(_newPassword, _userId); - } catch(e) { + return true; + } - console.log("changePassword :: changePassword : エラー->", e); - resolve(false); - return; + return false; - } - }); + } catch(e) { + + console.log("changePassword :: changePassword : エラー->", e); + return false; + + } } -//現在のパスワード確認用処理 -async function checkPassword(userId:string, currentPassword:string):Promise { - return new Promise((resolve) => { - db.all("SELECT * FROM USERS_PASSWORD WHERE userId=?", [userId], (err, datUser:IUserPassword[]) => { - //エラーならエラーと返す - if (err) { - resolve(false); - throw err; - } - //パスワードを比較して違ったら終わらせる - if (datUser[0].password !== currentPassword) { - resolve(false); - return; //認証失敗 - } else { - resolve(true); - return; //認証成功 - } - }); - }); +/** + * 現在のパスワードを確認する + * @param _userId + * @param _currentPassword + * @returns + */ +function checkPassword(_userId:string, _currentPassword:string):boolean { + const passwordData = db.prepare( + "SELECT * FROM USERS_PASSWORD WHERE userId=?" + ).get(_userId) as IUserPassword|undefined; + //パスワードデータがundefinedか、あるいは違うかを確認 + if (passwordData === undefined) return false; + if (passwordData.password !== _currentPassword) return false; + + return true; } diff --git a/src/actionHandler/auth/changeSessionName.ts b/src/actionHandler/auth/changeSessionName.ts index 7212b585..78ccb8c4 100644 --- a/src/actionHandler/auth/changeSessionName.ts +++ b/src/actionHandler/auth/changeSessionName.ts @@ -1,5 +1,6 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); /** * セッション名を変更 @@ -8,31 +9,21 @@ const db = new sqlite3.Database("./records/USER.db"); * @param _newName * @returns */ -export default async function changeSessionName( +export default function changeSessionName( _userId: string, _targetSessionId: string, _newName: string -):Promise { +):boolean { try { - return new Promise((resolve) => { - db.run( - ` - UPDATE USERS_SESSION SET sessionName=? - WHERE userId=? AND sessionId=? - `, - [_newName, _userId, _targetSessionId], - (err:Error) => { - //エラーハンドラ - if (err) { - console.log("changeSessionname :: db(セッション名変更) : エラー->", err); - return false; - } + db.prepare( + ` + UPDATE USERS_SESSION SET sessionName=? + WHERE userId=? AND sessionId=? + ` + ).run(_newName, _userId, _targetSessionId); - return true; - } - ); - }); + return true; } catch(e) { diff --git a/src/actionHandler/auth/checkSession.ts b/src/actionHandler/auth/checkSession.ts index e41a81bb..cce1c377 100644 --- a/src/actionHandler/auth/checkSession.ts +++ b/src/actionHandler/auth/checkSession.ts @@ -1,69 +1,54 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); import fetchUser from "../User/fetchUser"; import type { IUserSession } from "../../type/User"; import type IRequestSender from "../../type/requestSender"; -export default async function checkSession(RequestSender:IRequestSender) -:Promise { - return new Promise (async (resolve) => { - try { +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); + +/** + * セッションIdの一致を調べて認証する + * @param _RequestSender + * @returns + */ +export default function checkSession(_RequestSender:IRequestSender) +:boolean { + try { + + //データ確認 + if (_RequestSender.userId === undefined && _RequestSender.sessionId === undefined) { + return false; + } - //データ確認 - if (RequestSender.userId === undefined && RequestSender.sessionId === undefined) { - resolve(false); - return; - } + //ユーザー情報があるか、BANされているかどうかを確認 + const userInfo = fetchUser(_RequestSender.userId, null); + if (userInfo === null) { + return false; + } + if (userInfo.banned) { + return false; + } - //ユーザー情報があるか、BANされているかどうかを確認 - const userInfo = await fetchUser(RequestSender.userId, null); - if (userInfo === null) { - resolve(false); - return; - } - if (userInfo.banned) { - resolve(false); - return; + //セッションデータ取得用の + const stmtSessionData = db.prepare( + "SELECT * FROM USERS_SESSION WHERE userId = ?" + ); + //ループ用データ取得処理部分 + const iterateSessionData = stmtSessionData.iterate(_RequestSender.userId) as Iterable; + + //ループして一致するセッションデータを探す + for (const session of iterateSessionData) { + if (session.sessionId === _RequestSender.sessionId) { + return true; } + } - //ユーザーIdで検索、セッションIDを一致を探す - db.all( - "SELECT * FROM USERS_SESSION WHERE userId = ?", - [RequestSender.userId], - (err:Error, datSession:IUserSession[] - ) => { - if (err) { - console.log("checkSession :: db : ERROR ->", err); - resolve(false); - return; - } else { - //console.log("checkSession :: 検索結果->", datSession); - //データが空なら終わらせる - if (datSession.length === 0) { - resolve(false); - return; - } - - //セッションデータ分ループしてセッションIDの一致を探す - for (let dat of datSession) { - if (dat.sessionId === RequestSender.sessionId) { - resolve(true); - return; - } - } - - //ループ抜けちゃったら失敗として返す - resolve(false); - return; - } - }); + return false; - } catch(e) { + } catch(e) { - console.log("checkSesion :: エラー->", e); - resolve(false); - return; + console.log("checkSesion :: エラー->", e); + return false; - } - }); + } } diff --git a/src/actionHandler/auth/fetchSession.ts b/src/actionHandler/auth/fetchSession.ts index abe66e24..0259d7af 100644 --- a/src/actionHandler/auth/fetchSession.ts +++ b/src/actionHandler/auth/fetchSession.ts @@ -1,5 +1,6 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); import type { IUserSession } from "../../type/User"; @@ -9,30 +10,18 @@ import type { IUserSession } from "../../type/User"; * @param _indexNumber * @returns */ -export default async function fetchSession(_userId: string, _indexNumber: number) -:Promise { +export default function fetchSession(_userId: string, _indexNumber: number) +:IUserSession[] | null { try { //オフセットでずらすデータ数 const offsetNum = 10 * (_indexNumber-1 || 0); - return new Promise((resolve) => { - db.all( - "SELECT * FROM USERS_SESSION WHERE userId=? LIMIT 10 OFFSET ?", - [_userId, offsetNum], - (err:Error, sessionData:IUserSession[]) => { - //エラーハンドラ - if (err) { - resolve(null); - return; - } - - //データを返す - resolve(sessionData); - return; - } - ); - }); + const sessionData = db.prepare( + "SELECT * FROM USERS_SESSION WHERE userId=? LIMIT 10 OFFSET ?" + ).all(_userId, offsetNum) as IUserSession[]; + + return sessionData; } catch(e) { diff --git a/src/actionHandler/auth/sessionLogout.ts b/src/actionHandler/auth/sessionLogout.ts index aadb7e5e..4dffdd76 100644 --- a/src/actionHandler/auth/sessionLogout.ts +++ b/src/actionHandler/auth/sessionLogout.ts @@ -1,29 +1,18 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/USER.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/USER.db'); +db.pragma('journal_mode = WAL'); /** * セッションをログアウトさせる */ -export default async function sessionLogout(_userId:string, _targetSessionId:string):Promise { +export default function sessionLogout(_userId:string, _targetSessionId:string):boolean { try { - return new Promise((resolve) => { - db.run( - "DELETE FROM USERS_SESSION WHERE userId=? AND sessionId=?", - [_userId, _targetSessionId], - (err:Error) => { - //エラーハンドラ - if (err) { - console.log("sessionLogout :: db(削除) : エラー->", err); - resolve(false); - return; - } - - resolve(true); - return; - } - ) - }) + db.prepare( + "DELETE FROM USERS_SESSION WHERE userId=? AND sessionId=?" + ).run(_userId, _targetSessionId); + + return true; } catch(e) { diff --git a/src/actionHandler/onlineUsers/fetchOnlineUsers.ts b/src/actionHandler/onlineUsers/fetchOnlineUsers.ts index 9cf3f2c3..a788c304 100644 --- a/src/actionHandler/onlineUsers/fetchOnlineUsers.ts +++ b/src/actionHandler/onlineUsers/fetchOnlineUsers.ts @@ -1,33 +1,23 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/ONLINEUSERS.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ONLINEUSERS.db'); +db.pragma('journal_mode = WAL'); -export default async function fetchOnlineUsers():Promise { +/** + * オンラインのユーザーを取得 + * @returns + */ +export default function fetchOnlineUsers():string[]|null { try { - //オンラインのユーザーを取得 - return new Promise((resolve) => { - db.all( - ` - SELECT DISTINCT userId from ONLINE_USERS - `, - (err:Error, onlineUsers:{userId:string}[]) => { - if (err) { - resolve(null); - return; - } else { - //console.log("fetchOnlineUser :: db : onlineUsers->", onlineUsers); - //取得結果を配列にする - const onlineUsersArr:string[] = []; - for (let userId of onlineUsers) { - onlineUsersArr.push(userId["userId"]); - } + //オンラインユーザー取得 + const userOnline = db.prepare("SELECT DISTINCT userId from ONLINE_USERS").all() as {userId:string}[]; + //取得結果を配列にする + const onlineUsersArr:string[] = []; + for (const userId of userOnline) { + onlineUsersArr.push(userId.userId); + } - resolve(onlineUsersArr); - return; - } - } - ) - }); + return onlineUsersArr; } catch(e) { diff --git a/src/fileHandler/File/downloadfile.ts b/src/fileHandler/File/downloadfile.ts index 81373b9c..24e1021c 100644 --- a/src/fileHandler/File/downloadfile.ts +++ b/src/fileHandler/File/downloadfile.ts @@ -1,4 +1,4 @@ -import path from 'path'; +import path from 'node:path'; import checkSession from "../../actionHandler/auth/checkSession"; import fetchFileInfo from "../../util/FIle/fetchFileInfo"; import type IRequestSender from "../../type/requestSender"; @@ -12,7 +12,7 @@ export default async function downloadfile(req:any, res:any) { const metadata:{RequestSender:IRequestSender} = JSON.parse(req.body.metadata); //ファイル情報を取得 - const fileInfo = await fetchFileInfo(req.params.id); + const fileInfo = fetchFileInfo(req.params.id); if (fileInfo === null) { res.status(400).send({ result:"ERROR_FILE_MISSING" , data:null }); return; @@ -22,31 +22,31 @@ export default async function downloadfile(req:any, res:any) { const uploaderId:string = req.params.id.slice(0,8); if (fileInfo.isPublic) { - const filePath = path.join("./STORAGE/USERFILE/" + uploaderId + "/" + fileInfo.actualName); + const filePath = path.join(`./STORAGE/USERFILE/${uploaderId}/${fileInfo.actualName}`); res.download(filePath); return; - } else { - //送信者情報が無いならそうエラーを送信 - if (req.body.metadata === undefined) { - res.status(400).send({ result:"ERROR_FILE_IS_PRIVATE" }); - return; - } - - //送信者情報取り出し - const RequestSender:IRequestSender = metadata.RequestSender; - console.log("/downloadfile :: checkSession->", await checkSession(RequestSender)); - - //セッション認証する - if (await checkSession(RequestSender)) { - const filePath = path.join("./STORAGE/USERFILE/" + uploaderId + "/" + fileInfo.actualName); - res.download(filePath); - return; - } else { - res.status(400).send({ result:"ERROR_WRONG_SESSION" }); - return; - } } + //送信者情報が無いならそうエラーを送信 + if (req.body.metadata === undefined) { + res.status(400).send({ result:"ERROR_FILE_IS_PRIVATE" }); + return; + } + + //送信者情報取り出し + const RequestSender:IRequestSender = metadata.RequestSender; + console.log("/downloadfile :: checkSession->", await checkSession(RequestSender)); + + //セッション認証できたらファイル送信 + if (await checkSession(RequestSender)) { + const filePath = path.join(`./STORAGE/USERFILE/${uploaderId}/${fileInfo.actualName}`); + res.download(filePath); + return; + } + + res.status(400).send({ result:"ERROR_WRONG_SESSION" }); + return; + } catch(e) { console.log("/downloadfile :: エラー->", e); diff --git a/src/fileHandler/File/fetchFolderInfo.ts b/src/fileHandler/File/fetchFolderInfo.ts index dd3d46e9..8b8689e1 100644 --- a/src/fileHandler/File/fetchFolderInfo.ts +++ b/src/fileHandler/File/fetchFolderInfo.ts @@ -1,36 +1,26 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); -import { IFolder } from "../../type/File"; +import type { IFolder } from "../../type/File"; -export default async function fetchFolderInfo(userId:string, folderId:string):Promise { +/** + * フォルダ情報を取得 + * @param _userId + * @param _folderId + * @returns + */ +export default function fetchFolderInfo(_userId:string, _folderId:string):IFolder|null { try { - return new Promise((resolve) => { - db.all( - ` - SELECT * FROM FOLDERS - WHERE userId=? AND id=? - `, - [userId, folderId], - (err:Error, folderInfo:[IFolder]) => { - if (err) { - console.log("fetchFolderInfo :: db : エラー->", err); - resolve(null); - return; - } else { - console.log("fetchFolderInfo :: db : 結果->", folderInfo); - //もし最初のものが無いならnullを返す - if (folderInfo[0] === undefined) { - resolve(null); - } else { - resolve(folderInfo[0]); - } - return; - } - } - ); - }); + //フォルダ情報取得 + const folderInfo = db.prepare( + "SELECT * FROM FOLDERS WHERE userId=? AND id=?" + ).get(_userId, _folderId) as IFolder|undefined; + //undefinedならnull + if (folderInfo === undefined) return null; + + return folderInfo; } catch(e) { diff --git a/src/fileHandler/File/fetchfile.ts b/src/fileHandler/File/fetchfile.ts index cba22649..7a1b3cad 100644 --- a/src/fileHandler/File/fetchfile.ts +++ b/src/fileHandler/File/fetchfile.ts @@ -12,7 +12,7 @@ export default async function fetchfile(req:any, res:any) { try { //ファイル情報を取得 - const fileInfo = await fetchFileInfo(req.params.id); + const fileInfo = fetchFileInfo(req.params.id); if (fileInfo === null) { res.status(400).send({ result:"ERROR_FILE_MISSING" }); return; @@ -22,25 +22,25 @@ export default async function fetchfile(req:any, res:any) { if (fileInfo.isPublic) { res.status(200).send({ result:"SUCCESS" }); return; - } else { - //送信者情報が無いならそうエラーを送信 - if (req.body.metadata === undefined) { - res.status(400).send({ result:"ERROR_FILE_IS_PRIVATE" }); - return; - } + } + + //送信者情報が無いならそうエラーを送信 + if (req.body.metadata === undefined) { + res.status(400).send({ result:"ERROR_FILE_IS_PRIVATE" }); + return; + } - //送信者情報取り出し - const RequestSender:IRequestSender = JSON.parse(req.body.metadata); - //セッション認証する - if (await checkSession(RequestSender)) { - res.status(200).send({ result:"SUCCESS" }); - return; - } else { - res.status(400).send({ result:"ERROR_WRONG_SESSION" }); - return; - } + //送信者情報取り出し + const RequestSender:IRequestSender = JSON.parse(req.body.metadata); + //セッション認証できたら成功と送信 + if (await checkSession(RequestSender)) { + res.status(200).send({ result:"SUCCESS" }); + return; } + res.status(400).send({ result:"ERROR_WRONG_SESSION" }); + return; + } catch (e) { console.log("/uploadfile :: エラー!->", e); diff --git a/src/fileHandler/File/uploadfile.ts b/src/fileHandler/File/uploadfile.ts index 6d50923c..29f1664f 100644 --- a/src/fileHandler/File/uploadfile.ts +++ b/src/fileHandler/File/uploadfile.ts @@ -1,5 +1,7 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); + import fetchFolderInfo from "./fetchFolderInfo"; import type IRequestSender from "../../type/requestSender"; @@ -10,7 +12,7 @@ import type IRequestSender from "../../type/requestSender"; * @param res * @returns */ -export default async function uploadfile(req:any, res:any) { +export default function uploadfile(req:any, res:any) { try { console.log("/uploadfile :: ファイルが書き込まれました"); @@ -27,97 +29,77 @@ export default async function uploadfile(req:any, res:any) { const actualName = req.body.actualName; //チャンネルフォルダを作成するかどうかフラグ - let flagCreateChannelFolder:boolean = false; + let flagCreateChannelFolder = false; + //もしディレクトリIdがチャンネルフォルダに該当するならディレクトリが作成されているかを確認 //const regexChannelId = /^C\d{4}$/; const regexChannelId = /^C\d{4}_\d+$/; if (metadata.directory.match(regexChannelId) !== null) { //このチャンネル用のフォルダを取得 - const directoryForChannel = await fetchFolderInfo(metadata.RequestSender.userId, metadata.directory); + const directoryForChannel = fetchFolderInfo(metadata.RequestSender.userId, metadata.directory); console.log("/uploadfile :: フォルダあるかどうか->", directoryForChannel); //フォルダが無いのなら作るようにフラグをたてる if (directoryForChannel === null) flagCreateChannelFolder = true; } - db.serialize(() => { + //無いならファイルインデックス用テーブル作成 + db.exec( + ` + create table if not exists FILE${metadata.RequestSender.userId}( + id TEXT PRIMARY KEY, + userId TEXT DEFAULT ${metadata.RequestSender.userId}, + name TEXT NOT NULL, + actualName TEXT NOT NULL, + isPublic BOOLEAN NOT NULL DEFAULT 0, + type TEXT NOT NULL, + size NUMBER NOT NULL, + directory TEXT NOT NULL, + uploadedDate TEXT NOT NULL + ) + ` + ); - //この人用のファイルインデックス用テーブル作成 - db.run( + //このチャンネル用フォルダを作るオプションが有効なら作成 + if (flagCreateChannelFolder) { + db.prepare( + ` + INSERT INTO FOLDERS ( + id, userId, name, positionedDirectoryId + ) VALUES (?, ?, ?, ?) ` - create table if not exists FILE` + metadata.RequestSender.userId + `( - id TEXT PRIMARY KEY, - userId TEXT DEFAULT ` + metadata.RequestSender.userId + `, - name TEXT NOT NULL, - actualName TEXT NOT NULL, - isPublic BOOLEAN NOT NULL DEFAULT 0, - type TEXT NOT NULL, - size NUMBER NOT NULL, - directory TEXT NOT NULL, - uploadedDate TEXT NOT NULL - ) - `, - (err:Error) => { - if (err) { - res.status(500).send({ result:"ERROR_DB_THING" }); - return; - } - } + ).run( + metadata.directory, + metadata.RequestSender.userId, + metadata.directory, + "" ); + } - //チャンネル用フォルダを作るフラグが有効なら作成 - if (flagCreateChannelFolder) { - db.run( - ` - INSERT INTO FOLDERS ( - id, userId, name, positionedDirectoryId - ) VALUES (?, ?, ?, ?) - `, - [metadata.directory, metadata.RequestSender.userId, metadata.directory, ""], - (err:Error) => { - if (err) { - console.log("/uploadfile :: エラー->", err); - res.status(500).send({ result:"ERROR_DB_THING" }); - return; - } - } - ); - } - - //ファイルId生成 - const fileIdGenerated = generateFileId(metadata.RequestSender.userId); - //アップロード日時追加用 - const uploadedDate = new Date().toJSON(); + //ファイルId生成 + const fileIdGenerated = generateFileId(metadata.RequestSender.userId); + //アップロード日時追加用 + const uploadedDate = new Date().toJSON(); - //ファイルデータ書き込み - db.run( - ` - INSERT INTO FILE` + metadata.RequestSender.userId + ` ( - id, name, actualName, type, size, directory, uploadedDate - ) - VALUES (?, ?, ?, ?, ?, ?, ?) - `, - [ - fileIdGenerated, - req.file.originalname, - actualName, - req.file.mimetype, - req.file.size, - metadata.directory, - uploadedDate - ], - (err:Error) => { - if (err) { - console.log("uploadfile :: エラー->", err); - res.status(500).send({ result:"ERROR_DB_THING" }); - return; - } else { - res.status(200).send({ result:"SUCCESS", data:fileIdGenerated }); - return; - } - } + //ファイル情報をDBへ記録 + db.prepare( + ` + INSERT INTO FILE${metadata.RequestSender.userId} ( + id, name, actualName, type, size, directory, uploadedDate ) + VALUES (?, ?, ?, ?, ?, ?, ?) + ` + ).run( + fileIdGenerated, + req.file.originalname, + actualName, + req.file.mimetype, + req.file.size, + metadata.directory, + uploadedDate + ); - }); + res.status(200).send({ result:"SUCCESS", data:fileIdGenerated }); + return; } catch (e) { diff --git a/src/fileHandler/FileHandler.ts b/src/fileHandler/FileHandler.ts index 08b48fb2..d18db109 100644 --- a/src/fileHandler/FileHandler.ts +++ b/src/fileHandler/FileHandler.ts @@ -1,6 +1,6 @@ -import fs from "fs"; +import fs from "node:fs"; import multer from "multer"; -import path from 'path'; +import path from 'node:path'; import { ServerInfo } from "../db/InitServer"; import calcDirectorySize from "../util/FIle/calcDirectorySize"; import checkSession from "../actionHandler/auth/checkSession"; @@ -10,7 +10,7 @@ import type IRequestSender from "../type/requestSender"; // multer の設定(ディスクストレージを使用) const storage = multer.diskStorage({ - destination: async function (req, file, cb) { + destination: async (req, file, cb) => { console.log("FileHandler :: storage : req.body->", req.body); if (req.body !== undefined && Object.keys(req.body).length !== 0) { @@ -29,13 +29,13 @@ const storage = multer.diskStorage({ return; } //取り出した情報を数値化 - const fileSize = parseInt(contentLength); + const fileSize = Number.parseInt(contentLength); /////////////////////////////////////////////// //ディレクトリサイズを計算して超えていないか調べる //ディレクトリサイズを計算 - const currentFullSize = await calcDirectorySize(metadata.RequestSender.userId, ""); + const currentFullSize = calcDirectorySize(metadata.RequestSender.userId, ""); if (currentFullSize === null) { const error = new Error("ERROR_INTERNAL_THING"); cb(error, "STORAGE/TEMP"); @@ -57,15 +57,15 @@ const storage = multer.diskStorage({ //セッション認証 if (await checkSession(metadata.RequestSender)) { //このユーザー用のディレクトリ作成 - try{fs.mkdirSync("./STORAGE/USERFILE/" + metadata.RequestSender.userId);}catch(e){} + try{fs.mkdirSync(`./STORAGE/USERFILE/${metadata.RequestSender.userId}`);}catch(e){} // アップロードされるファイルの保存先 - cb(null, "STORAGE/USERFILE/"+metadata.RequestSender.userId); + cb(null, `STORAGE/USERFILE/${metadata.RequestSender.userId}`); return; - } else { - const error = new Error("ERROR_WRONG_SESSION"); - console.log("FileHandler :: storage : セッションエラー"); - cb(error, "STORAGE/TEMP"); } + + const error = new Error("ERROR_WRONG_SESSION"); + console.log("FileHandler :: storage : セッションエラー"); + cb(error, "STORAGE/TEMP"); } else { const error = new Error("ERROR_INFO_NOT_FOUND"); @@ -75,9 +75,9 @@ const storage = multer.diskStorage({ } }, - filename: function (req, file, cb) { + filename: (req, file, cb) => { //配置する用のファイル名設定 - const actualName = file.fieldname + '-' + Date.now() + path.extname(file.originalname); + const actualName = `${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`; //バックエンドに配置するファイル名をreq.bodyに含める req.body.actualName = actualName; diff --git a/src/socketHandler/Channel.ts b/src/socketHandler/Channel.ts index 20a73af6..4925574b 100644 --- a/src/socketHandler/Channel.ts +++ b/src/socketHandler/Channel.ts @@ -1,4 +1,4 @@ -import { Socket, Server } from "socket.io"; +import type { Socket, Server } from "socket.io"; import checkSession from "../actionHandler/auth/checkSession"; import createChannel from "../actionHandler/Channel/createChannel"; import fetchChannel from "../actionHandler/Channel/fetchChannel"; @@ -16,7 +16,7 @@ module.exports = (io:Server) => { io.on("connection", (socket:Socket) => { //チャンネル作成 - socket.on("createChannel", async (dat: + socket.on("createChannel", (dat: { RequestSender:IRequestSender, channelName:string, @@ -32,7 +32,7 @@ module.exports = (io:Server) => { */ /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::createChannel", { result:"ERROR_SESSION_ERROR", data:null }); return; } @@ -45,14 +45,14 @@ module.exports = (io:Server) => { } //ロール権限を確認する - const roleCheckResult = await roleCheck(dat.RequestSender.userId, "ChannelManage"); + const roleCheckResult = roleCheck(dat.RequestSender.userId, "ChannelManage"); if (!roleCheckResult) { socket.emit("RESULT::createChannel", { result:"ERROR_ROLE", data:null }); return; } //チャンネルを作成する - const createChannelResult = await createChannel( + const createChannelResult = createChannel( dat.channelName, dat.description, dat.isPrivate, @@ -71,7 +71,7 @@ module.exports = (io:Server) => { }); //チャンネル削除 - socket.on("deleteChannel", async (dat:{RequestSender:IRequestSender, channelId:string}) => { + socket.on("deleteChannel", (dat:{RequestSender:IRequestSender, channelId:string}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR"|"ERROR_CANNOT_DELETE_RANDOM", @@ -80,27 +80,27 @@ module.exports = (io:Server) => { */ /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::deleteChannel", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { - //Randomチャンネルは削除できないようにするため + //最初のRandomチャンネルは削除できないようにするため if (dat.channelId === "0001") { - socket.emit("RESULT::deleteChannel", { result:"ERROR_CANNOT_DELETE_RANDOM", data:null }); + socket.emit("RESULT::deleteChannel", { result:"ERROR_CANNOT_DELETE_0001", data:null }); return; } //ロール権限を確認する - const roleCheckResult = await roleCheck(dat.RequestSender.userId, "ChannelManage"); + const roleCheckResult = roleCheck(dat.RequestSender.userId, "ChannelManage"); if (!roleCheckResult) { //falseなら停止 socket.emit("RESULT::deleteChannel", { result:"ERROR_ROLE", data:null }); return; } //チャンネルを削除する - const deleteChannelResult = await deleteChannel( + const deleteChannelResult = deleteChannel( dat.RequestSender.userId, dat.channelId, ); @@ -119,7 +119,7 @@ module.exports = (io:Server) => { }); //チャンネルを更新 - socket.on("updateChannel", async ( + socket.on("updateChannel", ( dat: { RequestSender: IRequestSender, channelId: string, @@ -127,14 +127,14 @@ module.exports = (io:Server) => { } ) => { /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::updateChannel", { result:"ERROR_SESSION_ERROR" }); return; } try { //チャンネル更新 - const resultChannelUpdate = await updateChannel( + const resultChannelUpdate = updateChannel( dat.RequestSender.userId, dat.channelId, dat.channelInfo @@ -146,7 +146,7 @@ module.exports = (io:Server) => { socket.emit("RESULT::updateChannel", { result:"SUCCESS" }); //チャンネル情報を収集、送信 - const channelInfoUpdated = await fetchChannel(dat.channelId, dat.RequestSender.userId); + const channelInfoUpdated = fetchChannel(dat.channelId, dat.RequestSender.userId); if (channelInfoUpdated !== null) { io.to("LOGGEDIN").emit("RESULT::fetchChannelInfo", { result: "SUCCESS", @@ -167,16 +167,16 @@ module.exports = (io:Server) => { }); //チャンネル情報を取得する - socket.on("fetchChannelInfo", async (dat:{RequestSender:IRequestSender, channelId:string}) => { + socket.on("fetchChannelInfo", (dat:{RequestSender:IRequestSender, channelId:string}) => { /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchChannelInfo", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //チャンネル情報取得 - const channelInfo = await fetchChannel(dat.channelId, dat.RequestSender.userId); + const channelInfo = fetchChannel(dat.channelId, dat.RequestSender.userId); //結果送信 if (channelInfo !== null) { socket.emit("RESULT::fetchChannelInfo", { @@ -201,16 +201,16 @@ module.exports = (io:Server) => { }); //チャンネルを一覧で取得 - socket.on("fetchChannelList", async (dat:{RequestSender:IRequestSender}) => { + socket.on("fetchChannelList", (dat:{RequestSender:IRequestSender}) => { /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchChannelList", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //チャンネルリストを取得 - const channelList = await fetchChannelList(dat.RequestSender.userId); + const channelList = fetchChannelList(dat.RequestSender.userId); socket.emit("RESULT::fetchChannelList", { result:"SUCCESS", data:channelList }); } catch(e) { socket.emit("RESULT::fetchChannelList", { result:"ERROR_DB_THING", data:null }); @@ -218,7 +218,7 @@ module.exports = (io:Server) => { }); //チャンネルへ参加 - socket.on("joinChannel", async (dat:{ RequestSender:IRequestSender, channelId:string }) => { + socket.on("joinChannel", (dat:{ RequestSender:IRequestSender, channelId:string }) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -227,14 +227,14 @@ module.exports = (io:Server) => { */ //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::joinChannel", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //参加処理 - const joinChannelResult:boolean = await joinChannel(dat.RequestSender.userId, dat.channelId); + const joinChannelResult:boolean = joinChannel(dat.RequestSender.userId, dat.channelId); //結果を送信 if (joinChannelResult) { @@ -250,7 +250,7 @@ module.exports = (io:Server) => { }); //チャンネルから脱退 - socket.on("leaveChannel", async (dat:{ RequestSender:IRequestSender, channelId:string }) => { + socket.on("leaveChannel", (dat:{ RequestSender:IRequestSender, channelId:string }) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -259,14 +259,14 @@ module.exports = (io:Server) => { */ //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::leaveChannel", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //脱退処理 - const leaveChannelResult:boolean = await leaveChannel(dat.RequestSender.userId, dat.channelId); + const leaveChannelResult:boolean = leaveChannel(dat.RequestSender.userId, dat.channelId); //結果を送信 if (leaveChannelResult) { diff --git a/src/socketHandler/File.ts b/src/socketHandler/File.ts index a624d8a3..323d29ea 100644 --- a/src/socketHandler/File.ts +++ b/src/socketHandler/File.ts @@ -1,4 +1,4 @@ -import { Socket, Server } from "socket.io"; +import type { Socket, Server } from "socket.io"; import checkSession from "../actionHandler/auth/checkSession"; import type IRequestSender from "../type/requestSender"; @@ -16,7 +16,7 @@ module.exports = (io:Server) => { io.on("connection", (socket:Socket) => { //自分のファイルインデックスを取得 - socket.on("fetchFileIndex", async ( + socket.on("fetchFileIndex", ( dat: { RequestSender: IRequestSender, directory: string, @@ -31,7 +31,7 @@ module.exports = (io:Server) => { */ //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchFileIndex", { result: "ERROR_WRONG_SESSION", data: null @@ -41,7 +41,7 @@ module.exports = (io:Server) => { try { //ファイルインデックス取得 - const fileIndex = await fetchFileIndex( + const fileIndex = fetchFileIndex( dat.RequestSender.userId, dat.directory, dat.searchQuery @@ -69,9 +69,9 @@ module.exports = (io:Server) => { }); //ファイルを削除する - socket.on("deleteFile", async (dat:{RequestSender:IRequestSender, fileId:string}) => { + socket.on("deleteFile", (dat:{RequestSender:IRequestSender, fileId:string}) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::deleteFile", { result: "ERROR_WRONG_SESSION", data: null @@ -81,7 +81,7 @@ module.exports = (io:Server) => { try { //ファイル削除し結果を受け取る - const deleteFileResult = await deleteFile(dat.RequestSender.userId, dat.fileId); + const deleteFileResult = deleteFile(dat.RequestSender.userId, dat.fileId); //結果に応じて送信 if (deleteFileResult) { socket.emit("RESULT::deleteFile", {result:"SUCCESS", data:dat.fileId}); @@ -94,10 +94,10 @@ module.exports = (io:Server) => { }); //ファイル単体情報の取得 - socket.on("fetchFileInfo", async (dat:{RequestSender:IRequestSender, fileId:string}) => { + socket.on("fetchFileInfo", (dat:{RequestSender:IRequestSender, fileId:string}) => { try { //ファイル情報の取得 - const fileInfo = await fetchFileInfo(dat.fileId); + const fileInfo = fetchFileInfo(dat.fileId); //nullならそう返す if (fileInfo === null) { socket.emit( @@ -145,7 +145,7 @@ module.exports = (io:Server) => { } //セッション認証をする - const authSessionResult = await checkSession(dat.RequestSender); + const authSessionResult = checkSession(dat.RequestSender); //結果に応じてそう送信 if (authSessionResult) { @@ -179,14 +179,14 @@ module.exports = (io:Server) => { }); //フォルダーを取得 - socket.on("fetchFolders", async ( + socket.on("fetchFolders", ( dat: { RequestSender: IRequestSender, positionedDirectoryId: string } ) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchFolders", { result: "ERROR_WRONG_SESSION", data: null @@ -196,7 +196,7 @@ module.exports = (io:Server) => { try { //フォルダーを取得 - const folder = await fetchFolders( + const folder = fetchFolders( dat.RequestSender.userId, dat.positionedDirectoryId ); @@ -213,9 +213,9 @@ module.exports = (io:Server) => { }); //全ファイルの容量を取得 - socket.on("calcFullFolderSize", async (dat:{RequestSender:IRequestSender}) => { + socket.on("calcFullFolderSize", (dat:{RequestSender:IRequestSender}) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::calcFullFolderSize", { result: "ERROR_WRONG_SESSION", data: null @@ -225,7 +225,7 @@ module.exports = (io:Server) => { try { //容量を取得する - const fileSize = await calcFullFolderSize(dat.RequestSender.userId); + const fileSize = calcFullFolderSize(dat.RequestSender.userId); //結果に応じてそう返す if (fileSize !== null) { socket.emit("RESULT::calcFullFolderSize", { result:"SUCCESS", data:fileSize }); @@ -239,9 +239,9 @@ module.exports = (io:Server) => { }); //ファイルの公開設定をトグル - socket.on("toggleFileIsPublic", async (dat:{RequestSender:IRequestSender, fileId:string}) => { + socket.on("toggleFileIsPublic", (dat:{RequestSender:IRequestSender, fileId:string}) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::toggleFileIsPublic", { result: "ERROR_WRONG_SESSION", data: null @@ -251,7 +251,7 @@ module.exports = (io:Server) => { try { //ファイルの公開設定をトグル、結果としてboolを受け取る - const resultToggle = await toggleFileIsPublic(dat.RequestSender.userId, dat.fileId); + const resultToggle = toggleFileIsPublic(dat.RequestSender.userId, dat.fileId); //結果に応じて送信 if (resultToggle) { socket.emit("RESULT::toggleFileIsPublic", { @@ -274,7 +274,7 @@ module.exports = (io:Server) => { }); //フォルダーを作成する - socket.on("createFolder", async ( + socket.on("createFolder", ( dat: { RequestSender: IRequestSender, folderName: string, @@ -282,7 +282,7 @@ module.exports = (io:Server) => { } ) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::createFolder", { result: "ERROR_WRONG_SESSION", data: null @@ -292,7 +292,7 @@ module.exports = (io:Server) => { try { //フォルダーを作成する - const createFolderResult = await createFolder( + const createFolderResult = createFolder( dat.RequestSender.userId, dat.folderName, dat.directoryId @@ -311,9 +311,9 @@ module.exports = (io:Server) => { }); //フォルダーと中身のすべてを削除 - socket.on("deleteFolder", async (dat:{RequestSender:IRequestSender, folderId:string}) => { + socket.on("deleteFolder", (dat:{RequestSender:IRequestSender, folderId:string}) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::deleteFolder", { result: "ERROR_WRONG_SESSION", data: null @@ -329,7 +329,7 @@ module.exports = (io:Server) => { try { //フォルダーの削除、結果受け取り - const deleteFolderResult = await deleteFolder(dat.RequestSender.userId, dat.folderId); + const deleteFolderResult = deleteFolder(dat.RequestSender.userId, dat.folderId); //結果に応じてそう送信 if (deleteFolderResult) { socket.emit("RESULT::deleteFolder", { result:"SUCCESS", data:null }); diff --git a/src/socketHandler/Message.ts b/src/socketHandler/Message.ts index 74f9c687..247e3e91 100644 --- a/src/socketHandler/Message.ts +++ b/src/socketHandler/Message.ts @@ -1,4 +1,4 @@ -import { Socket, Server } from "socket.io"; +import type { Socket, Server } from "socket.io"; import checkSession from "../actionHandler/auth/checkSession"; import saveMessage from "../actionHandler/Message/saveMessage"; import fetchHistory from "../actionHandler/Message/fetchHistory"; @@ -35,14 +35,14 @@ module.exports = (io:Server) => { */ //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::sendMessage", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //メッセージデータを処理 - const messageData = await saveMessage( + const messageData = saveMessage( dat.RequestSender.userId, dat.message ); @@ -100,7 +100,7 @@ module.exports = (io:Server) => { }); //メッセージの削除 - socket.on("deleteMessage", async ( + socket.on("deleteMessage", ( dat: { RequestSender: IRequestSender channelId: string, @@ -115,14 +115,14 @@ module.exports = (io:Server) => { */ //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::deleteMessage", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //削除処理 - const deleteMessageResult = await deleteMessage( + const deleteMessageResult = deleteMessage( dat.channelId, dat.messageId, dat.RequestSender.userId @@ -138,10 +138,10 @@ module.exports = (io:Server) => { } }); return; - } else { - socket.emit("RESULT::deleteMessage", { result:"ERROR_DB_THING", data:null }); - return; } + + socket.emit("RESULT::deleteMessage", { result:"ERROR_DB_THING", data:null }); + return; } catch(e) { console.log("socket(Message) :: deleteMessage : エラー->", e); return; @@ -158,7 +158,7 @@ module.exports = (io:Server) => { } ) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::editMessage", { result:"ERROR_SESSION_ERROR", data:null }); return; } @@ -228,7 +228,7 @@ module.exports = (io:Server) => { }) //履歴の取得 - socket.on("fetchHistory", async ( + socket.on("fetchHistory", ( dat: { RequestSender: IRequestSender, channelId: string, @@ -248,7 +248,7 @@ module.exports = (io:Server) => { */ //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchHistory", { result:"ERROR_SESSION_ERROR", data:null }); return; } @@ -259,7 +259,7 @@ module.exports = (io:Server) => { history: IMessage[], atTop: boolean, atEnd: boolean - }|null = await fetchHistory(dat.channelId, dat.fetchingPosition); + }|null = fetchHistory(dat.channelId, dat.fetchingPosition); //データを送信 socket.emit( @@ -279,7 +279,7 @@ module.exports = (io:Server) => { }); //リアクション追加処理 - socket.on("reactMessage", async ( + socket.on("reactMessage", ( dat: { RequestSender: IRequestSender, channelId: string, @@ -288,14 +288,14 @@ module.exports = (io:Server) => { } ) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::reactMessage", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //リアクション追加処理、結果受け取り - const reactResult:boolean = await reactMessage( + const reactResult:boolean = reactMessage( dat.channelId, dat.messageId, dat.reactionName, @@ -305,7 +305,7 @@ module.exports = (io:Server) => { //リアクション結果に応じて処理 if (reactResult) { //処理した後のメッセージ取得 - const messageNow = await fetchMessage(dat.channelId, dat.messageId); + const messageNow = fetchMessage(dat.channelId, dat.messageId); //メッセージが取得できたら成功と送信 if (messageNow !== null) { //更新させる @@ -325,27 +325,27 @@ module.exports = (io:Server) => { }); //メッセージの最終既読メッセ時間を保存する - socket.on("setMessageReadTime", async ( + socket.on("setMessageReadTime", ( dat: { RequestSender: IRequestSender, channelId: string, messageTime: string }) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::setMessageReadTime", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //もし時間の値がDate型に使えないならエラーとして返す - if (isNaN(new Date(dat.messageTime).valueOf())) { + if (Number.isNaN(new Date(dat.messageTime).valueOf())) { socket.emit("RESULT::setMessageReadTime", { result:"ERROR_TIME_CANNOT_VALIDATE", data:null }); return; } //最新既読時間書き込み - const setMessageReadTimeResult:boolean = await setMessageReadTime( + const setMessageReadTimeResult:boolean = setMessageReadTime( dat.RequestSender.userId, dat.channelId, dat.messageTime @@ -364,20 +364,20 @@ module.exports = (io:Server) => { }); //チャンネルの既読時間を取得 - socket.on("getMessageReadTime", async ( + socket.on("getMessageReadTime", ( dat: { RequestSender: IRequestSender } ) => { //セッション認証 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::getMessageReadTime", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //既読状態取得 - const getMessageReadTimeResult:IMessageReadTime|null = await getMessageReadTime(dat.RequestSender.userId); + const getMessageReadTimeResult:IMessageReadTime|null = getMessageReadTime(dat.RequestSender.userId); //nullじゃないならデータを送信 if (getMessageReadTimeResult !== null) { diff --git a/src/socketHandler/OnlineUsers.ts b/src/socketHandler/OnlineUsers.ts index 09e188bd..4701284b 100644 --- a/src/socketHandler/OnlineUsers.ts +++ b/src/socketHandler/OnlineUsers.ts @@ -1,12 +1,10 @@ -import { Socket, Server } from "socket.io"; +import type { Socket, Server } from "socket.io"; -import authLogin from "../actionHandler/auth/authLogin"; -import { IUserInfo } from "../type/User"; -import addUserOnline from "../util/onlineUsers/addUserOnline"; import fetchOnlineUsers from "../actionHandler/onlineUsers/fetchOnlineUsers"; -import IRequestSender from "../type/requestSender"; import checkSession from "../actionHandler/auth/checkSession"; +import type IRequestSender from "../type/requestSender"; + module.exports = (io:Server) => { io.on("connection", (socket:Socket) => { @@ -30,7 +28,7 @@ module.exports = (io:Server) => { try { //認証処理 - const onlineUsers = await fetchOnlineUsers(); + const onlineUsers = fetchOnlineUsers(); //console.log("onlineUsers :: fetchOnlineUsers : onlineUsers->", onlineUsers); diff --git a/src/socketHandler/Role.ts b/src/socketHandler/Role.ts index 59abef05..51bb7582 100644 --- a/src/socketHandler/Role.ts +++ b/src/socketHandler/Role.ts @@ -1,4 +1,4 @@ -import { Socket, Server } from "socket.io"; +import type { Socket, Server } from "socket.io"; import fetchRoles from "../actionHandler/Role/fetchRoles"; import checkSession from "../actionHandler/auth/checkSession"; @@ -35,7 +35,7 @@ module.exports = (io:Server) => { try { //全ロールを取得 - const roles = await fetchRoles(); + const roles = fetchRoles(); //nullじゃないならそれを返す if (roles !== null) { @@ -65,7 +65,7 @@ module.exports = (io:Server) => { try { //ロールを検索 - const roleResult = await searchRole(dat.searchQuery, dat.pageIndex); + const roleResult = searchRole(dat.searchQuery, dat.pageIndex); //nullじゃないなら結果送信 if (roleResult !== null) { socket.emit("RESULT::searchRole", { result:"SUCCESS", data:roleResult }); @@ -120,19 +120,19 @@ module.exports = (io:Server) => { try { //ロール権限の確認 - if (!(await roleCheck(dat.RequestSender.userId, "RoleManage"))) { + if (!(roleCheck(dat.RequestSender.userId, "RoleManage"))) { socket.emit("RESULT::addRole", { result:"ERROR_ROLE", data:false }); return; } //ロールを付与 - const addRoleResult:boolean = await addRole(dat.RequestSender.userId, dat.targetUserId, dat.roleId); + const addRoleResult:boolean = addRole(dat.RequestSender.userId, dat.targetUserId, dat.roleId); //結果に応じてそう返す if (addRoleResult) { socket.emit("RESULT::addRole", { result:"SUCCESS", data:addRoleResult }); //成功したのならそのユーザーの情報を全体に送信 - const userInfo = await fetchUser(dat.targetUserId, null); + const userInfo = fetchUser(dat.targetUserId, null); io.emit("RESULT::fetchUserInfo", { result:"SUCCESS", data:userInfo }); } else { socket.emit("RESULT::addRole", { result:"ERROR_DB_THING", data:addRoleResult }); @@ -165,19 +165,19 @@ module.exports = (io:Server) => { try { //ロール権限の確認 - if (!(await roleCheck(dat.RequestSender.userId, "RoleManage"))) { + if (!(roleCheck(dat.RequestSender.userId, "RoleManage"))) { socket.emit("RESULT::unlinkRole", { result:"ERROR_ROLE", data:null }); return; } //ロールを付与 - const unlinkRoleResult:boolean = await unlinkRole(dat.RequestSender.userId, dat.targetUserId, dat.roleId); + const unlinkRoleResult:boolean = unlinkRole(dat.RequestSender.userId, dat.targetUserId, dat.roleId); //結果に応じてそう返す if (unlinkRoleResult) { socket.emit("RESULT::unlinkRole", { result:"SUCCESS", data:unlinkRoleResult }); //成功したのならそのユーザーの情報を全体に送信 - const userInfo = await fetchUser(dat.targetUserId, null); + const userInfo = fetchUser(dat.targetUserId, null); io.emit("RESULT::fetchUserInfo", { result:"SUCCESS", data:userInfo }); } else { socket.emit("RESULT::unlinkRole", { result:"ERROR_DB_THING", data:unlinkRoleResult }); @@ -212,7 +212,7 @@ module.exports = (io:Server) => { try { //ロール権限の確認 - if (!(await roleCheck(dat.RequestSender.userId, "RoleManage"))) { + if (!(roleCheck(dat.RequestSender.userId, "RoleManage"))) { socket.emit("RESULT::createRole", { result:"ERROR_ROLE", data:null }); return; } @@ -224,7 +224,7 @@ module.exports = (io:Server) => { socket.emit("RESULT::createRole", { result:"SUCCESS", data:null }); //作成したロール情報を送信 - const roleInfo:IUserRole = await fetchRoleSingle(createRoleResult); + const roleInfo:IUserRole = fetchRoleSingle(createRoleResult); io.emit("RESULT::fetchRoleSingle", { result:"SUCCESS", data:roleInfo }); } else { socket.emit("RESULT::createRole", { result:"ERROR_DB_THING", data:null }); @@ -258,19 +258,19 @@ module.exports = (io:Server) => { } //ロール権限の確認 - if (!(await roleCheck(dat.RequestSender.userId, "RoleManage"))) { + if (!(roleCheck(dat.RequestSender.userId, "RoleManage"))) { socket.emit("RESULT::updateRole", { result:"ERROR_ROLE", data:null }); return; } //ロールの更新、結果を格納 - const updateRoleResult = await updateRole(dat.RequestSender.userId, dat.roleData); + const updateRoleResult = updateRole(dat.RequestSender.userId, dat.roleData); //結果に応じて送信 if (updateRoleResult) { socket.emit("RESULT::updateRole", {result:"SUCCESS", data:null}); //現在のロール情報を全員に送信 - const roleInfo = await fetchRoleSingle(dat.roleData.roleId); + const roleInfo = fetchRoleSingle(dat.roleData.roleId); io.emit("RESULT::fetchRoleSingle", { result:"SUCCESS", data:roleInfo }); } else { socket.emit("RESULT::updateRole", {result:"ERROR_DB_THING", data:null}); @@ -304,13 +304,13 @@ module.exports = (io:Server) => { } //ロール権限の確認 - if (!(await roleCheck(dat.RequestSender.userId, "RoleManage"))) { + if (!(roleCheck(dat.RequestSender.userId, "RoleManage"))) { socket.emit("RESULT::deleteRole", { result:"ERROR_ROLE", data:null }); return; } //ロールの更新、結果を格納 - const deleteRoleResult = await deleteRole(dat.roleId); + const deleteRoleResult = deleteRole(dat.roleId); //結果に応じて送信 if (deleteRoleResult) { socket.emit("RESULT::deleteRole", {result:"SUCCESS", data:null}); diff --git a/src/socketHandler/Server.ts b/src/socketHandler/Server.ts index 03adcd19..1cc382e7 100644 --- a/src/socketHandler/Server.ts +++ b/src/socketHandler/Server.ts @@ -1,4 +1,4 @@ -import { Socket, Server } from "socket.io"; +import type { Socket, Server } from "socket.io"; import { ServerInfo } from "../db/InitServer"; import checkSession from "../actionHandler/auth/checkSession"; import updateServerConfig from "../actionHandler/Server/updateServerConfig"; @@ -23,6 +23,7 @@ module.exports = (io:Server) => { //転送するインスタンス情報を削るためにクローンする const ServerInfoLimited:IServerInfo = structuredClone(ServerInfo); //招待コードを削除 + // biome-ignore lint/performance/noDelete: 完全に削除したいため delete ServerInfoLimited.registration.invite.inviteCode; //返す @@ -30,7 +31,7 @@ module.exports = (io:Server) => { }); //全てのインスタンス情報を取得 - socket.on("fetchServerInfoFull", async (dat:{RequestSender:IRequestSender}) => { + socket.on("fetchServerInfoFull", (dat:{RequestSender:IRequestSender}) => { /* 返し : { result: "SUCCESS"|"ERROR_MISSINGROLE", @@ -39,13 +40,13 @@ module.exports = (io:Server) => { */ /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchServerInfoFull", { result:"ERROR_SESSION_ERROR", data:null }); return; } //権限確認 - const roleCheckResult = await roleCheck(dat.RequestSender.userId, "ServerManage"); + const roleCheckResult = roleCheck(dat.RequestSender.userId, "ServerManage"); if (!roleCheckResult) { socket.emit("RESULT::fetchServerInfoFull", { result:"ERROR_ROLE", data:null }); return; @@ -55,7 +56,7 @@ module.exports = (io:Server) => { }); //サーバー設定の更新 - socket.on("updateServerConfig", async (dat:{ RequestSender:IRequestSender, ServerConfig:IServerInfo["config"]}) => { + socket.on("updateServerConfig", (dat:{ RequestSender:IRequestSender, ServerConfig:IServerInfo["config"]}) => { /* 返し : { result: "SUCCESS"|"ERROR_INTERNAL_ERROR|ERROR_DB_THING|ERROR_SESSION_ERROR", @@ -64,14 +65,14 @@ module.exports = (io:Server) => { */ /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::updateServerConfig", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //権限確認 - const roleCheckResult = await roleCheck(dat.RequestSender.userId, "ServerManage"); + const roleCheckResult = roleCheck(dat.RequestSender.userId, "ServerManage"); if (!roleCheckResult) { socket.emit("RESULT::updateServerConfig", { result:"ERROR_ROLE", data:null }); return; @@ -86,6 +87,7 @@ module.exports = (io:Server) => { //転送するインスタンス情報を削るためにクローンする const ServerInfoLimited:IServerInfo = structuredClone(ServerInfo); //招待コードを削除 + // biome-ignore lint/performance/noDelete: 完全に削除したいため delete ServerInfoLimited.registration.invite.inviteCode; //サーバー情報を返す io.emit("RESULT::fetchServerInfoLimited", { result:"SUCCESS", data:ServerInfoLimited }); @@ -98,7 +100,7 @@ module.exports = (io:Server) => { }); //インスタンスの基本情報の更新 - socket.on("updateServerInfo", async ( + socket.on("updateServerInfo", ( dat:{ RequestSender: IRequestSender, servername: IServerInfo["servername"] @@ -106,14 +108,14 @@ module.exports = (io:Server) => { } ) => { /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::updateServerInfo", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //権限確認 - const roleCheckResult = await roleCheck(dat.RequestSender.userId, "ServerManage"); + const roleCheckResult = roleCheck(dat.RequestSender.userId, "ServerManage"); if (!roleCheckResult) { socket.emit("RESULT::updateServerInfo", { result:"ERROR_ROLE", data:null }); return; @@ -126,6 +128,7 @@ module.exports = (io:Server) => { //転送するインスタンス情報を削るためにクローンする const ServerInfoLimited:IServerInfo = structuredClone(ServerInfo); //招待コードを削除 + // biome-ignore lint/performance/noDelete: 完全に削除したいため delete ServerInfoLimited.registration.invite.inviteCode; //全員にサーバー情報を返す diff --git a/src/socketHandler/User.ts b/src/socketHandler/User.ts index 46ff3537..39ae2367 100644 --- a/src/socketHandler/User.ts +++ b/src/socketHandler/User.ts @@ -1,4 +1,4 @@ -import { Socket, Server } from "socket.io"; +import type { Socket, Server } from "socket.io"; import fetchUserConfig from "../actionHandler/User/fetchUserConfig"; import changeUserName from "../actionHandler/User/changeUserName"; import checkSession from "../actionHandler/auth/checkSession"; @@ -22,7 +22,7 @@ module.exports = (io:Server) => { io.on("connection", (socket:Socket) => { //ユーザーの設定データを取得 - socket.on("fetchUserConfig", async (RequestSender:IRequestSender) => { + socket.on("fetchUserConfig", (RequestSender:IRequestSender) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -31,14 +31,14 @@ module.exports = (io:Server) => { */ /* セッション認証 */ - if (!(await checkSession(RequestSender))) { + if (!(checkSession(RequestSender))) { socket.emit("RESULT::fetchUserConfig", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //設定データ読み取り - const configData = await fetchUserConfig(RequestSender.userId); + const configData = fetchUserConfig(RequestSender.userId); //返す socket.emit("RESULT::fetchUserConfig", { result:"SUCCESS", data:configData }); @@ -49,7 +49,7 @@ module.exports = (io:Server) => { }); //ユーザーごとのチャンネル順序を取得 - socket.on("fetchUserChannelOrder", async (dat:{RequestSender:IRequestSender}) => { + socket.on("fetchUserChannelOrder", (dat:{RequestSender:IRequestSender}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -58,14 +58,14 @@ module.exports = (io:Server) => { */ /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchUserChannelOrder", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //チャンネル順序の読み取り - const resultChannelOrder = await fetchUserChannelOrder(dat.RequestSender.userId); + const resultChannelOrder = fetchUserChannelOrder(dat.RequestSender.userId); //返す socket.emit("RESULT::fetchUserChannelOrder", { result:"SUCCESS", data:resultChannelOrder }); @@ -76,7 +76,7 @@ module.exports = (io:Server) => { }); //ユーザーの通知リストを取得 - socket.on("fetchUserInbox", async (dat:{RequestSender:IRequestSender}) => { + socket.on("fetchUserInbox", (dat:{RequestSender:IRequestSender}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -85,14 +85,14 @@ module.exports = (io:Server) => { */ /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchUserInbox", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //通知Inbox取得 - const inbox = await fetchUserInbox(dat.RequestSender.userId); + const inbox = fetchUserInbox(dat.RequestSender.userId); //とれたならそのまま渡す if (inbox) { @@ -113,9 +113,9 @@ module.exports = (io:Server) => { itemId: string }[] = [] //キューが動作しているかどうか - let ActingremoteFromUserInbox:boolean = false; + const ActingremoteFromUserInbox = false; //Socketハンドラ - socket.on("removeFromUserInbox", async ( + socket.on("removeFromUserInbox", ( dat: { RequestSender: IRequestSender, inboxCategory: "mention"|"event", @@ -124,24 +124,42 @@ module.exports = (io:Server) => { } ) => { /* セッション認証 */ - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::removeFromUserInbox", { result:"ERROR_SESSION_ERROR", data:null }); return; } //キューに追加 + /* queueRemove.push({ userId: dat.RequestSender.userId, inboxCategory: dat.inboxCategory, channelId: dat.channelId, itemId: dat.inboxItemId }); + */ //console.log("User :: socket(removeFromUserInbox) : ActingremoteFromUserInbox->", ActingremoteFromUserInbox); //もしすでに処理始めているなら停止 - if (ActingremoteFromUserInbox) return; + //if (ActingremoteFromUserInbox) return; try { + //Inboxから削除、結果受け取り(引数にキューのデータを使う) + const inboxEditResult = removeFromUserInbox( + dat.RequestSender.userId, + dat.inboxCategory, + dat.channelId, + dat.inboxItemId + ); + + //結果を送信 + if (inboxEditResult) { + socket.emit("RESULT::removeFromUserInbox", { result:"SUCCESS", data:true }); + } else { + socket.emit("RESULT::removeFromUserInbox", { result:"SUCCESS_NO_CHANGES", data:false }); + } + + /* //処理をしていると設定 ActingremoteFromUserInbox = true; //ループで通知削除処理 @@ -149,7 +167,7 @@ module.exports = (io:Server) => { //キューからデータ取得 const q = queueRemove[0]; //Inboxから削除、結果受け取り(引数にキューのデータを使う) - const inboxEditResult = await removeFromUserInbox( + const inboxEditResult = removeFromUserInbox( q.userId, q.inboxCategory, q.channelId, @@ -172,6 +190,7 @@ module.exports = (io:Server) => { //処理をやめたと設定 ActingremoteFromUserInbox = false; + */ } catch(e) { socket.emit("RESULT::removeFromUserInbox", { result:"ERROR_INTERNAL_THING", data:null }); return; @@ -179,7 +198,7 @@ module.exports = (io:Server) => { }); //設定データを保存する - socket.on("saveUserConfig", async (dat:{RequestSender:IRequestSender, config:IUserConfig}) => { + socket.on("saveUserConfig", (dat:{RequestSender:IRequestSender, config:IUserConfig}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -188,14 +207,14 @@ module.exports = (io:Server) => { */ //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::saveUserConfig", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //書き込み - const saveUserConfigResult:boolean = await saveUserConfig(dat.RequestSender.userId, dat.config); + const saveUserConfigResult:boolean = saveUserConfig(dat.RequestSender.userId, dat.config); //結果に応じて結果と設定データを返す if (saveUserConfigResult) { socket.emit("RESULT::saveUserConfig", { result:"SUCCESS", data:dat.config}); @@ -208,7 +227,7 @@ module.exports = (io:Server) => { }); //ユーザーごとのチャンネル順序を保存 - socket.on("saveUserChannelOrder", async (dat:{RequestSender:IRequestSender, channelOrder:IChannelOrder}) => { + socket.on("saveUserChannelOrder", (dat:{RequestSender:IRequestSender, channelOrder:IChannelOrder}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -217,14 +236,14 @@ module.exports = (io:Server) => { */ //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::saveUserChannelOrder", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //書き込み、結果受け取り - const resultSaveUserChannelOrder:boolean = await saveUserChannelOrder(dat.RequestSender.userId, dat.channelOrder); + const resultSaveUserChannelOrder:boolean = saveUserChannelOrder(dat.RequestSender.userId, dat.channelOrder); //結果に応じて結果と設定データを返す if (resultSaveUserChannelOrder) { socket.emit("RESULT::saveUserChannelOrder", { result:"SUCCESS", data:null}); @@ -237,7 +256,7 @@ module.exports = (io:Server) => { }); //一人分のユーザー情報取得(ユーザーIDから) - socket.on("fetchUserInfo", async (dat:{RequestSender:IRequestSender, userId:string}) => { + socket.on("fetchUserInfo", (dat:{RequestSender:IRequestSender, userId:string}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -245,13 +264,13 @@ module.exports = (io:Server) => { } */ //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchUserInfo", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { - const userInfo = await fetchUser(dat.userId, null); + const userInfo = fetchUser(dat.userId, null); socket.emit("RESULT::fetchUserInfo", { result:"SUCCESS", data:userInfo }); } catch(e) { socket.emit("RESULT::fetchUserInfo", { result:"ERROR_DB_THING", data:null }); @@ -260,7 +279,7 @@ module.exports = (io:Server) => { }); //複数ユーザーの取得 - socket.on("fetchUserAll", async (dat:{RequestSender:IRequestSender, indexPage:number}) => { + socket.on("fetchUserAll", (dat:{RequestSender:IRequestSender, indexPage:number}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -269,14 +288,14 @@ module.exports = (io:Server) => { */ //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchUserAll", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //ユーザーを取得 - const fetchUserAllResult = await fetchUserAll(dat.indexPage); + const fetchUserAllResult = fetchUserAll(dat.indexPage); //結果に応じてデータを送信 if (fetchUserAllResult !== null) { socket.emit("RESULT::fetchUserAll", { @@ -295,7 +314,7 @@ module.exports = (io:Server) => { }); //ユーザー名で検索して一括取得 - socket.on("searchUserInfo", async ( + socket.on("searchUserInfo", ( dat: { RequestSender: IRequestSender, userName: string, //検索文字列 @@ -305,14 +324,14 @@ module.exports = (io:Server) => { ) => { console.log("User :: searchUserInfo : data->", dat); //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::searchUserInfo", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //情報検索、取得 - const userInfos = await searchUser( + const userInfos = searchUser( dat.userName, dat.rule, dat.channelId ); @@ -323,7 +342,7 @@ module.exports = (io:Server) => { }); //ユーザー名の変更 - socket.on("changeUserName", async (dat:{RequestSender:IRequestSender, userName:string}) => { + socket.on("changeUserName", (dat:{RequestSender:IRequestSender, userName:string}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR", @@ -332,17 +351,18 @@ module.exports = (io:Server) => { */ //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::changeUserName", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //ユーザー名を変更 - await changeUserName(dat.RequestSender.userId, dat.userName); + changeUserName(dat.RequestSender.userId, dat.userName); socket.emit("RESULT::changeUserName", { result:"SUCCESS", data:null }); + //現在のユーザー情報を取得して送信 - const userInfo = await fetchUser(dat.RequestSender.userId, null); + const userInfo = fetchUser(dat.RequestSender.userId, null); io.emit("RESULT::fetchUserInfo", { result:"SUCCESS", data:userInfo }); } catch(e) { socket.emit("RESULT::changeUserName", { result:"ERROR_DB_THING", data:null }); @@ -350,7 +370,7 @@ module.exports = (io:Server) => { }); //ユーザーをBANする - socket.on("banUser", async (dat:{RequestSender:IRequestSender, targetUserId:string}) => { + socket.on("banUser", (dat:{RequestSender:IRequestSender, targetUserId:string}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR"|"ERROR_ROLE", @@ -359,7 +379,7 @@ module.exports = (io:Server) => { */ //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::banUser", { result:"ERROR_SESSION_ERROR", data:null }); return; } @@ -367,31 +387,31 @@ module.exports = (io:Server) => { try { //もし操作者と標的が一緒なら停止 if (dat.RequestSender.userId === dat.targetUserId) { - socket.emit("RESULT::banUser", { result:"ERROR_DB_THING", data:false }); + socket.emit("RESULT::banUser", { result:"ERROR_CANNOT_BAN_YOURSELF", data:false }); return; } //ユーザー情報が空、あるいはホスト権限を持つユーザーなら停止 - const userInfo = await fetchUser(dat.targetUserId, null); + const userInfo = fetchUser(dat.targetUserId, null); if (userInfo === null || userInfo.userId === "HOST") { socket.emit("RESULT::banUser", { result:"ERROR_DB_THING", data:false }); return; } //権限確認 - if (!(await roleCheck(dat.RequestSender.userId, "UserManage"))) { + if (!(roleCheck(dat.RequestSender.userId, "UserManage"))) { socket.emit("RESULT::banUser", { result:"ERROR_ROLE", data:false }); return; } //BAN処理 - const banUserResult = await banUser(dat.RequestSender.userId, dat.targetUserId); + const banUserResult = banUser(dat.RequestSender.userId, dat.targetUserId); //結果を返す if (banUserResult) { socket.emit("RESULT::banUser", { result:"SUCCESS", data:true }); //現在のユーザー情報を取得して送信 - const userInfo = await fetchUser(dat.targetUserId, null); + const userInfo = fetchUser(dat.targetUserId, null); io.emit("RESULT::fetchUserInfo", { result:"SUCCESS", data:userInfo }); } else { socket.emit("RESULT::banUser", { result:"ERROR_DB_THING", data:false }); @@ -403,7 +423,7 @@ module.exports = (io:Server) => { }); //ユーザーのBAN状態を解除する - socket.on("pardonUser", async (dat:{RequestSender:IRequestSender, targetUserId:string}) => { + socket.on("pardonUser", (dat:{RequestSender:IRequestSender, targetUserId:string}) => { /* 返し : { result: "SUCCESS"|"ERROR_DB_THING"|"ERROR_SESSION_ERROR"|"ERROR_ROLE", @@ -412,33 +432,33 @@ module.exports = (io:Server) => { */ //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::pardonUser", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //ユーザー情報が空なら停止 - const userInfo = await fetchUser(dat.targetUserId, null); + const userInfo = fetchUser(dat.targetUserId, null); if (userInfo === null) { socket.emit("RESULT::pardonUser", { result:"ERROR_DB_THING", data:false }); return; } //権限確認 - if (!(await roleCheck(dat.RequestSender.userId, "UserManage"))) { + if (!(roleCheck(dat.RequestSender.userId, "UserManage"))) { socket.emit("RESULT::pardonUser", { result:"ERROR_ROLE", data:false }); return; } //BANの解除処理 - const pardonUserResult = await pardonUser(dat.RequestSender.userId, dat.targetUserId); + const pardonUserResult = pardonUser(dat.RequestSender.userId, dat.targetUserId); //結果を返す if (pardonUserResult) { socket.emit("RESULT::pardonUser", { result:"SUCCESS", data:true }); //現在のユーザー情報を取得して送信 - const userInfo = await fetchUser(dat.targetUserId, null); + const userInfo = fetchUser(dat.targetUserId, null); io.emit("RESULT::fetchUserInfo", { result:"SUCCESS", data:userInfo }); } else { socket.emit("RESULT::pardonUser", { result:"ERROR_DB_THING", data:false }); diff --git a/src/socketHandler/auth.ts b/src/socketHandler/auth.ts index eb957077..32c791ab 100644 --- a/src/socketHandler/auth.ts +++ b/src/socketHandler/auth.ts @@ -8,17 +8,17 @@ import fetchSession from "../actionHandler/auth/fetchSession"; import { ServerInfo } from "../db/InitServer"; import fetchUser from "../actionHandler/User/fetchUser"; import addUserOnline from "../util/onlineUsers/addUserOnline"; +import changeSessionName from "../actionHandler/auth/changeSessionName"; +import sessionLogout from "../actionHandler/auth/sessionLogout"; import type IRequestSender from "../type/requestSender"; import type { IUserInfo } from "../type/User"; -import sessionLogout from "../actionHandler/auth/sessionLogout"; -import changeSessionName from "../actionHandler/auth/changeSessionname"; module.exports = (io:Server) => { io.on("connection", (socket:Socket) => { //ログイン認証 - socket.on("authLogin", async (dat:{username:string, password:string}) => { + socket.on("authLogin", (dat:{username:string, password:string}) => { /* 返し : { result: "SUCCESS"|"ERROR_WRONGINFO", @@ -32,7 +32,7 @@ module.exports = (io:Server) => { authResult:boolean, UserInfo: IUserInfo|null, sessionId: string|null - } = await authLogin(dat.username, dat.password); + } = authLogin(dat.username, dat.password); console.log("auth :: authLogin : authResult->", authData); @@ -48,7 +48,7 @@ module.exports = (io:Server) => { ) { //参加したチャンネル全部分のSocketルーム参加 if (authData.UserInfo.channelJoined !== undefined) { - for (let channelId of authData.UserInfo.channelJoined) { + for (const channelId of authData.UserInfo.channelJoined) { socket.join(channelId); } } @@ -58,7 +58,7 @@ module.exports = (io:Server) => { socket.join(authData.UserInfo.userId); //オンラインのユーザーとして記録 - const addUserOnlineResult = await addUserOnline(socket.id, authData.UserInfo.userId, authData.sessionId); + const addUserOnlineResult = addUserOnline(socket.id, authData.UserInfo.userId, authData.sessionId); //オンラインになる人としてユーザーIdをログイン済みの全員に送信 io.to("LOGGEDIN").emit("addOnlineUser", {data:authData.UserInfo.userId}); @@ -83,13 +83,13 @@ module.exports = (io:Server) => { }); //セッションのみでの認証 - socket.on("authSession", async (dat:{userId:string, sessionId:string}) => { + socket.on("authSession", (dat:{userId:string, sessionId:string}) => { //セッション確認 - if (!(await checkSession(dat))) { //失敗 + if (!(checkSession(dat))) { //失敗 socket.emit("RESULT::authSession", { result:"ERROR_SESSION_ERROR", data:false }); } else { //成功 //参加チャンネル分、Socketルームへ参加させる - const userInfo = await fetchUser(dat.userId, null); + const userInfo = fetchUser(dat.userId, null); //ユーザー情報が空ならエラー if (userInfo === null) { socket.emit("RESULT::authSession", { result:"ERROR_DB_THING", data:false }); @@ -97,7 +97,7 @@ module.exports = (io:Server) => { } //情報が空じゃなければチャンネルへの参加処理 - for (let channelId of userInfo.channelJoined) { + for (const channelId of userInfo.channelJoined) { socket.join(channelId); } //認証済みの人として参加 @@ -109,7 +109,7 @@ module.exports = (io:Server) => { socket.emit("RESULT::authSession", { result:"SUCCESS", data:true }); //オンラインのユーザーとして記録 - await addUserOnline(socket.id, dat.userId, dat.sessionId); + addUserOnline(socket.id, dat.userId, dat.sessionId); //オンラインになる人としてユーザーIdをログイン済みの全員に送信 io.to("LOGGEDIN").emit("addOnlineUser", {data:dat.userId}); } @@ -155,7 +155,7 @@ module.exports = (io:Server) => { }); //パスワード変更 - socket.on("changePassword", async ( + socket.on("changePassword", ( dat:{RequestSender:IRequestSender, currentPassword:string, newPassword:string} ) => { /* @@ -166,7 +166,7 @@ module.exports = (io:Server) => { */ //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::changePassword", { result:"ERROR_SESSION_ERROR", data:null }); return; } @@ -174,7 +174,7 @@ module.exports = (io:Server) => { try { //パスワードを変更し結果を受け取る const changePasswordResult = - await changePassword( + changePassword( dat.RequestSender.userId, dat.currentPassword, dat.newPassword @@ -192,16 +192,16 @@ module.exports = (io:Server) => { }); //セッション情報を取得 - socket.on("fetchSession", async (dat:{RequestSender:IRequestSender, indexNum:number}) => { + socket.on("fetchSession", (dat:{RequestSender:IRequestSender, indexNum:number}) => { //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::fetchSession", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //セッション情報を取得 - const sessionData = await fetchSession(dat.RequestSender.userId, dat.indexNum); + const sessionData = fetchSession(dat.RequestSender.userId, dat.indexNum); //nullじゃなければ送信 if (sessionData !== null) { socket.emit("RESULT::fetchSession", { result:"SUCCESS", data:sessionData }); @@ -219,7 +219,7 @@ module.exports = (io:Server) => { }); //セッション名前 - socket.on("changeSessionName", async ( + socket.on("changeSessionName", ( dat: { RequestSender: IRequestSender, targetSessionId: string, @@ -227,14 +227,14 @@ module.exports = (io:Server) => { } ) => { //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::changeSessionName", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //セッション名を変更 - const changeSessionname:boolean = await changeSessionName(dat.RequestSender.userId, dat.targetSessionId, dat.newName); + const changeSessionname:boolean = changeSessionName(dat.RequestSender.userId, dat.targetSessionId, dat.newName); //成功ならそう送信 if (changeSessionname) { socket.emit("RESULT::changeSessionName", { result:"SUCCESS", data:null }); @@ -251,16 +251,16 @@ module.exports = (io:Server) => { }); //セッション情報をログアウトさせる - socket.on("sessionLogout", async (dat:{RequestSender: IRequestSender, targetSessionId:string}) => { + socket.on("sessionLogout", (dat:{RequestSender: IRequestSender, targetSessionId:string}) => { //セッション確認 - if (!(await checkSession(dat.RequestSender))) { + if (!(checkSession(dat.RequestSender))) { socket.emit("RESULT::sessionLogout", { result:"ERROR_SESSION_ERROR", data:null }); return; } try { //セッションデータを削除する - const sessionLogoutResult = await sessionLogout(dat.RequestSender.userId, dat.targetSessionId); + const sessionLogoutResult = sessionLogout(dat.RequestSender.userId, dat.targetSessionId); if (sessionLogoutResult) { socket.emit("RESULT::sessionLogout", { result:"SUCCESS", data:null }); diff --git a/src/util/FIle/calcDirectorySize.ts b/src/util/FIle/calcDirectorySize.ts index 7adba746..81126ee8 100644 --- a/src/util/FIle/calcDirectorySize.ts +++ b/src/util/FIle/calcDirectorySize.ts @@ -1,137 +1,61 @@ -import sqlite3 from "sqlite3"; -import { IFile } from "../../type/File"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); + +import type { IFile } from "../../type/File"; /** * 指定ディレクトリのサイズを計算 */ export default function calcDirectorySize( - userId: string, - directoryId: string = "" -):Promise|null { + _userId: string, + _directoryId = "" +):number|null { try { //ディレクトリのトータル容量 - let totalSize:number = 0; + let totalSize = 0; //ルートディレクトリ(すべてのトータル容量)を計算するかどうか // "" = ルートディレクトリ - let optionCalculatingRootDirectory:boolean = directoryId===''; - - //容量計算 - return new Promise((resolve) => { - //ルートディレクトリを計算するかどうかで処理を変える - if (optionCalculatingRootDirectory) { - - db.serialize(() => { - //この人用のファイルインデックス用テーブルが無ければここで作成 - db.run( - ` - create table if not exists FILE` + userId + `( - id TEXT PRIMARY KEY, - userId TEXT DEFAULT ` + userId + `, - name TEXT NOT NULL, - actualName TEXT NOT NULL, - isPublic BOOLEAN NOT NULL DEFAULT 0, - type TEXT NOT NULL, - size NUMBER NOT NULL, - directory TEXT NOT NULL, - uploadedDate TEXT NOT NULL - ) - `, - (err:Error) => { - if (err) { - resolve(null); - return; - } - } - ); - - db.all( - ` - SELECT * FROM FILE` + userId + ` - ` - , - (err:Error, files:IFile[]) => { - if (err) { - console.log("calcDirectorySize :: db : エラー->", err); - resolve(null); - return; - } else { - console.log("calcDirectorySize :: db : 結果(filesの数)->", files.length); - - //ループして容量を加算 - for (let file of files) { - totalSize += file.size; - } - - console.log("calcDirectorySize :: db : 結果->", totalSize); - - resolve(totalSize); - return; - } - } - ); - }); + const optionCalculatingRootDirectory:boolean = _directoryId===''; - } else { + //この人用のファイルインデックス用テーブルが無ければここで作成 + db.exec( + ` + create table if not exists FILE${_userId}( + id TEXT PRIMARY KEY, + userId TEXT DEFAULT ${_userId}, + name TEXT NOT NULL, + actualName TEXT NOT NULL, + isPublic BOOLEAN NOT NULL DEFAULT 0, + type TEXT NOT NULL, + size NUMBER NOT NULL, + directory TEXT NOT NULL, + uploadedDate TEXT NOT NULL + ) + ` + ); - db.serialize(() => { - //この人用のファイルインデックス用テーブルが無ければここで作成 - db.run( - ` - create table if not exists FILE` + userId + `( - id TEXT PRIMARY KEY, - userId TEXT DEFAULT ` + userId + `, - name TEXT NOT NULL, - actualName TEXT NOT NULL, - isPublic BOOLEAN NOT NULL DEFAULT 0, - type TEXT NOT NULL, - size NUMBER NOT NULL, - directory TEXT NOT NULL, - uploadedDate TEXT NOT NULL - ) - `, - (err:Error) => { - if (err) { - resolve(null); - return; - } - } - ); + //ファイル情報を格納する変数 + let files:IFile[] = []; - db.all( - ` - SELECT * FROM FILE` + userId + ` - WHERE directory=? - ` - , - [directoryId], - (err:Error, files:IFile[]) => { - if (err) { - console.log("calcDirectorySize :: db : エラー->", err); - resolve(null); - return; - } else { - console.log("calcDirectorySize :: db : 結果(filesの数)->", files.length); - - //ループして容量を加算 - for (let file of files) { - totalSize += file.size; - } - - console.log("calcDirectorySize :: db : 結果->", totalSize); - - resolve(totalSize); - return; - } - } - ); + //すべてのファイル分容量計算をするかどうかでファイル取得のSQL構文を変える + if (optionCalculatingRootDirectory) { + files = db.prepare( + `SELECT * FROM FILE${_userId}` + ).all() as IFile[]; + } else { + files = db.prepare( + `SELECT * FROM FILE${_userId} WHERE directory=?` + ).all(_directoryId) as IFile[]; + } - }); + //ループして総容量変数へ加算していく + for (const f of files) { + totalSize += f.size; + } - } - - }); + return totalSize; } catch(e) { diff --git a/src/util/FIle/fetchFileInfo.ts b/src/util/FIle/fetchFileInfo.ts index 3347c9dc..35a2aeaa 100644 --- a/src/util/FIle/fetchFileInfo.ts +++ b/src/util/FIle/fetchFileInfo.ts @@ -1,36 +1,28 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); + import type { IFile } from "../../type/File"; -export default async function fetchFileInfo(fileId: string):Promise { +/** + * ファイル情報を取得する + * @param _fileId + * @returns + */ +export default function fetchFileInfo(_fileId: string):IFile|null { try { //ファイルIdからアップロード主を抜き出す - const userId = fileId.slice(0,8); + const userId = _fileId.slice(0,8); + + //ファイル情報を取得 + const fileInfo = db.prepare( + `SELECT * FROM FILE${userId} WHERE id=?` + ).get(_fileId) as IFile | undefined; + //undefinedならnullを返す + if (fileInfo === undefined) return null; - return new Promise((resolve) => { - db.all( - ` - SELECT * FROM FILE` + userId + ` WHERE id=? - `, - fileId, - (err:Error, fileInfo:[IFile]) => { - if (err) { - console.log("fetchFileInfo :: db : エラー->", err); - resolve(null); - return; - } else { - //console.log("fetchFileInfo :: db : 結果->", fileInfo); - if (fileInfo[0] !== undefined) { - resolve(fileInfo[0]); - } else { - resolve(null); - } - return; - } - } - ); - }); + return fileInfo; } catch(e) { diff --git a/src/util/FIle/fetchFolders.ts b/src/util/FIle/fetchFolders.ts index 4cd6f647..93d3008b 100644 --- a/src/util/FIle/fetchFolders.ts +++ b/src/util/FIle/fetchFolders.ts @@ -1,33 +1,32 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/FILEINDEX.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/FILEINDEX.db'); +db.pragma('journal_mode = WAL'); + import type { IFolder } from "../../type/File"; -export default async function fetchFolders( - userId: string, - positionedDirectoryId: string = "" -):Promise { +/** + * 指定のフォルダに属するフォルダId群を取得する + * @param _userId + * @param _positionedDirectoryId + * @returns + */ +export default function fetchFolders( + _userId: string, + _positionedDirectoryId = "" +):IFolder[]|null { try { - - return new Promise((resolve) => { - db.all( - ` - SELECT * FROM FOLDERS - WHERE userId=? AND positionedDirectoryId=? - `, - [userId, positionedDirectoryId], - (err:Error, fileInfo:IFolder[]) => { - if (err) { - console.log("fetchFolders :: db : エラー->", err); - resolve(null); - return; - } else { - console.log("fetchFolders :: db : 結果->", fileInfo); - resolve(fileInfo); - return; - } - } - ); - }); + + //フォルダId群を取得する + const folders = db.prepare( + ` + SELECT * FROM FOLDERS + WHERE userId=? AND positionedDirectoryId=? + ` + ).all(_userId, _positionedDirectoryId) as IFolder[] | undefined; + //フォルダ情報がundefinedならnull + if (folders === undefined) return null; + + return folders; } catch(e) { diff --git a/src/util/checkDataIntegrality.ts b/src/util/checkDataIntegrality.ts deleted file mode 100644 index d0bf1bfc..00000000 --- a/src/util/checkDataIntegrality.ts +++ /dev/null @@ -1,37 +0,0 @@ -//データが正規のものか確認する -export default function checkDataIntegrality(dat:any|null, paramRequire:string[], funcName:string):boolean { -// //そもそも送信者情報が無効ならfalse -// if (dat.reqSender.userid === undefined || dat.reqSender.sessionid === undefined) return false; - -// try{ -// //パラメータが足りているか確認 -// for ( let termIndex in paramRequire ) { -// if ( dat[paramRequire[termIndex]] === undefined ) { -// console.log("-------------------------------"); -// console.log("ERROR IN ", dat); -// console.log("does not have enough parameter > " + paramRequire[termIndex]); -// console.log("-------------------------------"); - -// } - -// } - -// } -// catch(e) { -// console.log("checkDataIntegrality :: " + funcName + " : (userid:" + dat.reqSender.userid + ") error -> " + e); -// return false; - -// } - -// //セッションIDの確認 -// if ( !auth.checkUserSession(dat.reqSender) ) { return false; } - -// console.log("checkDataIntegrality :: (userid:" + dat.reqSender.userid + ") 確認できた => " + funcName); - - - - //現在は全部trueと返す - //確認できたと返す - return true; - -} \ No newline at end of file diff --git a/src/util/genLinkPreview.ts b/src/util/genLinkPreview.ts index 45a2b29a..d68a5fdb 100644 --- a/src/util/genLinkPreview.ts +++ b/src/util/genLinkPreview.ts @@ -1,8 +1,12 @@ import sqlite3 from "sqlite3"; -import { IMessage } from "../type/Message"; +import type { IMessage } from "../type/Message"; const db = new sqlite3.Database("./records/MESSAGE.db"); import ogs from 'open-graph-scraper'; +import Database from 'better-sqlite3'; +const _db = new Database('./records/MESSAGE.db'); +_db.pragma('journal_mode = WAL'); + //取得できるOpenGraphデータのinterface interface IOGData { ogSiteName: string, @@ -28,34 +32,41 @@ interface IURLParsed { favicon: string }; +/** + * URLからプレビューデータを取得してメッセージデータへ格納する + * @param _urls + * @param _channelId + * @param _messageId + * @returns + */ export default async function genLinkPreview( - urls:RegExpMatchArray, - channelId:string, - messageId: string + _urls:RegExpMatchArray, + _channelId:string, + _messageId: string ):Promise { try { //プレビューデータの格納用変数 - let previewResult:IMessage["linkData"] = { + const previewResult:IMessage["linkData"] = { //"0":{} }; //URLの配列分フェッチ、パース処理 - for (let index in urls) { + for (const index in _urls) { //もしURLが画像用ならここで処理して終了 - if (urls[index].match(/(https?:\/\/.*\.(?:png|jpg|gif))/g) !== null) { + if (_urls[index].match(/(https?:\/\/.*\.(?:png|jpg|gif))/g) !== null) { previewResult[index] = { contentType: "image", mediaType: "image", - url: urls[index], + url: _urls[index], }; } else { //Twitter用だったら二重処理 - if (urls[index].includes("fxtwitter")) { + if (_urls[index].includes("fxtwitter")) { //プレビューデータ化処理 - const resultForThis = await fetchURLForTwitter(urls[index]); + const resultForThis = await fetchURLForTwitter(_urls[index]); //挿入 :: ToDo //previewResult = { // "0": resultForThis @@ -63,7 +74,7 @@ export default async function genLinkPreview( previewResult[index] = resultForThis; } else { //プレビューデータ化処理 - const resultForThis = await fetchURL(urls[index]); + const resultForThis = await fetchURL(_urls[index]); //挿入 :: ToDo previewResult[index] = resultForThis; } @@ -72,26 +83,15 @@ export default async function genLinkPreview( } //プレビューデータの書き込み処理 - return new Promise((resolve)=> { - db.run( - ` - UPDATE C` + channelId + ` SET - linkData=? - WHERE messageId=? - `, - [JSON.stringify(previewResult), messageId], - (err:Error) => { - if (err) { - console.log("genLinkPreview :: エラー->", err); - resolve(null); - return; - } else { - resolve(previewResult); - return; - } - } - ); - }); + _db.prepare( + ` + UPDATE C${_channelId} SET + linkData=? + WHERE messageId=? + ` + ).run(JSON.stringify(previewResult), _messageId); + + return previewResult; } catch(e) { diff --git a/src/util/onlineUsers/addUserOnline.ts b/src/util/onlineUsers/addUserOnline.ts index 182c1850..f52b71e9 100644 --- a/src/util/onlineUsers/addUserOnline.ts +++ b/src/util/onlineUsers/addUserOnline.ts @@ -1,5 +1,6 @@ -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/ONLINEUSERS.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ONLINEUSERS.db'); +db.pragma('journal_mode = WAL'); /** * オンラインユーザーへユーザーId、SocketIDを追加し結果を返す @@ -8,27 +9,19 @@ const db = new sqlite3.Database("./records/ONLINEUSERS.db"); * @param sessionId * @returns boolean */ -export default async function addUserOnline(socketId:string, userId:string, sessionId:string) -:Promise { +export default function addUserOnline( + _socketId: string, + _userId: string, + _sessionId: string +): boolean { try { - return new Promise((resolve) => { - db.run( - ` - INSERT INTO ONLINE_USERS (socketId,userId,sessionId) VALUES (?,?,?) - `, - [socketId, userId, sessionId], - (err:Error) => { - if (err) { - resolve(false); - return; - } else { - resolve(true); - return; - } - } - ); - }); + //オンラインユーザーを記録 + db.prepare( + "INSERT INTO ONLINE_USERS (socketId,userId,sessionId) VALUES (?,?,?)" + ).run(_socketId, _userId, _sessionId); + + return true; } catch(e) { diff --git a/src/util/onlineUsers/removeUserOnlineBySocketId.ts b/src/util/onlineUsers/removeUserOnlineBySocketId.ts index 70bf5a8b..a01bb9dd 100644 --- a/src/util/onlineUsers/removeUserOnlineBySocketId.ts +++ b/src/util/onlineUsers/removeUserOnlineBySocketId.ts @@ -1,6 +1,6 @@ -import sqlite3 from "sqlite3"; -import { IUserInfo } from "../../type/User"; -const db = new sqlite3.Database("./records/ONLINEUSERS.db"); +import Database from 'better-sqlite3'; +const db = new Database('./records/ONLINEUSERS.db'); +db.pragma('journal_mode = WAL'); /** * オンラインユーザーリストから一致するSocketIDを @@ -8,84 +8,42 @@ const db = new sqlite3.Database("./records/ONLINEUSERS.db"); * @param socketId * @returns string */ -export default async function removeUserOnlineBySocketId(socketId:string) -:Promise { +export default function removeUserOnlineBySocketId(_socketId:string) +: string | null { try { //console.log("removeUserOnlineBySocketId :: socketId->", socketId); - //切断するユーザーIdを取得 - const userIdDisconnecting:string|null = await new Promise((resolve) => { - db.all( - ` - SELECT userId FROM ONLINE_USERS WHERE socketId=? - `, - socketId, - (err:Error, onlineUsers:IUserInfo[]) => { - if (err) { - console.log("removeUserOnlineBySocketId :: db : エラー->", err); - resolve(null); - return; - } else { - //配列の長さを確認して返す、空だったらnull - if (onlineUsers.length !== 0) { - resolve(onlineUsers[0].userId); - } else { - resolve(null); - } - return; - } - } - ); - }); + const userIdDisconnectingRaw = db.prepare( + "SELECT userId FROM ONLINE_USERS WHERE socketId=?" + ).get(_socketId) as {userId: string} | undefined; - //もしユーザーIdがnullだったらそう返して停止 - if (userIdDisconnecting === null) { + console.log("removeUserOnlineBySocketId :: userId->", userIdDisconnectingRaw); + + //もしユーザーIdデータがundefinedだったら停止 + if (userIdDisconnectingRaw === undefined) { return null; } - //切断処理とそのユーザーがまだいるかどうか判断処理 - return new Promise((resolve) => { - db.serialize(() => { - //SocketIDに該当する接続を削除 - db.run( - ` - DELETE FROM ONLINE_USERS WHERE socketId=? - `, - socketId, - (err:Error, onlineUsers:any[]) => { - if (err) { - console.log("removeUserOnlineBySocketId :: db(DELETE socketId) : エラー->, err"); - return; - } - } - ); + //抽出 + const userIdDisconnecting = userIdDisconnectingRaw.userId; + + //ユーザーをオンラインリストから削除 + db.prepare("DELETE FROM ONLINE_USERS WHERE socketId=?").run(_socketId); + + //同じユーザーIdがまだオンラインかどうか数えて調べる + const userCountRaw = db.prepare( + "SELECT COUNT(*) FROM ONLINE_USERS WHERE userId=?" + ).get(userIdDisconnecting) as {"COUNT(*)":number}; + const userCount = userCountRaw["COUNT(*)"]; - //切断するユーザーIdのSocket数を調べて0なら切断したと送信 - db.all( - ` - SELECT COUNT(*) FROM ONLINE_USERS WHERE userId=? - `, - userIdDisconnecting, - (err:Error, onlineUsersNum:{"COUNT(*)":number}[]) => { - if (err) { - console.log("removeUserOnlineBySocketId :: db(COUNT(*)) : エラー->", err); - } else { - //console.log("removeUserOnlineBySocketId :: db(COUNT(*)) : カウント->", onlineUsersNum); - //ここで接続数調べ - if (onlineUsersNum[0]['COUNT(*)'] === 0) { - resolve(userIdDisconnecting); - return; - } else { - resolve(null); - return; - } - } - } - ); + //他にオンラインのセッションがあるならnull + if (userCount !== 0) { + return null; + } - }); - }); + //このユーザーIdは切断したと返す + return userIdDisconnecting; } catch(e) { diff --git a/src/util/roleCheck.ts b/src/util/roleCheck.ts index 02938880..b1ae0b96 100644 --- a/src/util/roleCheck.ts +++ b/src/util/roleCheck.ts @@ -1,72 +1,67 @@ -//権限チェック -import sqlite3 from "sqlite3"; -const db = new sqlite3.Database("./records/ROLE.db"); import fetchUser from "../actionHandler/User/fetchUser"; -import { IUserRole } from "../type/User"; +import type { IUserRole } from "../type/User"; + +import Database from 'better-sqlite3'; +const db = new Database('./records/ROLE.db'); +db.pragma('journal_mode = WAL'); //ロールのJSONデータをキーで参照できるように type UserRoleKey = keyof IUserRole; -export default async function roleCheck(userId:string, termChecking:UserRoleKey):Promise { +/** + * 指定のユーザーIdが指定項目の権限を持っているかどうか調べる + * @param _userId 調べるユーザーId + * @param _termChecking 調べるロール内の権限 + * @returns + */ +export default function roleCheck(_userId:string, _termChecking:UserRoleKey):boolean { try { - return new Promise(async (resolve) => { - //SYSTEMならtrue - if (userId === "SYSTEM") { - resolve(true); - return; - } + //SYSTEMならtrue + if (_userId === "SYSTEM") { + return true; + } + + //ユーザー情報を取得する + const userInfo = fetchUser(_userId, null); + //ユーザーがなければ取りやめ + if (userInfo === null) { + return false + } - //ユーザー情報を取得する - const userInfo = await fetchUser(userId, null); - //ユーザーがなければ取りやめ - if (userInfo === null) { - resolve(false); - return; + //SQLでWHERE条件を指定するためのSQL文用変数 + //👇このSQL文を使ってロールIDに引っかかるROLEをすべて取得する + let sqlContextWhereFull = ""; + //ロールの数分条件文追加 + for (const index in userInfo.role) { + //追加するのが最後のロールIDかどうか + const isLastRole:boolean = (userInfo.role.length-1)===Number.parseInt(index); + + //SQLへ条件追加するこのロール用の文 + let sqlContextWhereSingle = ""; + //SQLへ条件追加する文を作成、最後ならANDをつけない + if (isLastRole) { + sqlContextWhereSingle = `roleId='${userInfo.role[index]}'`; + } else { + sqlContextWhereSingle = `roleId='${userInfo.role[index]}' OR `; } - //SQLでWHERE条件を指定するためのSQL文用変数 - //👇このSQL文を使ってロールIDに引っかかるROLEをすべて取得する - let sqlContextWhereFull = ""; - //ロールの数分条件文追加 - for (let index in userInfo.role) { - //追加するのが最後のロールIDかどうか - const isLastRole:boolean = (userInfo.role.length-1)===parseInt(index); + sqlContextWhereFull += sqlContextWhereSingle; + } - //SQLへ条件追加するこのロール用の文 - let sqlContextWhereSingle:string = ""; - //SQLへ条件追加する文を作成、最後ならANDをつけない - if (isLastRole) { - sqlContextWhereSingle = "roleId='" + userInfo.role[index] + "'"; - } else { - sqlContextWhereSingle = "roleId='" + userInfo.role[index] + "' OR "; - } + //ロールデータを取得するSQL処理 + const stmtRoles = db.prepare(`SELECT * FROM ROLES WHERE ${sqlContextWhereFull}`); + //データ取得をループする処理 + const iterateRoles = stmtRoles.iterate() as Iterable; - sqlContextWhereFull += sqlContextWhereSingle; + //ループでロールの該当権限が有効かどうか調べる + for (const role of iterateRoles) { + if (role[_termChecking]) { + return true; } + } - //ユーザーが持つロールの権限データをすべて取得する - db.all("SELECT * FROM ROLES WHERE " + sqlContextWhereFull, (err:Error, datRoles:IUserRole[]) => { - if (err) { - console.log("roleCheck :: db : エラー->", err); - resolve(false); - } else { - //console.log("roleCheck :: db : 結果->", datRoles); - //ロール分調べて権限が足りるか調べる - for (let role of datRoles) { - //権限の値がtrueなら「できる」と返す - //SQLiteでのboolは数字なので=が二つ - if (role[termChecking] == true) { - resolve(true); - return; - } - } - //ループ抜けちゃったらできないと返す - resolve(false); - return; - } - }); - }); + return false; } catch(e) {