diff options
| -rw-r--r-- | default-config.json | 135 | ||||
| -rw-r--r-- | res/css/setup.css | 48 | ||||
| -rw-r--r-- | res/img/welcome.webp | bin | 0 -> 53258 bytes | |||
| -rw-r--r-- | res/index.html | 2 | ||||
| -rw-r--r-- | res/langs/en.json | 228 | ||||
| -rw-r--r-- | res/setup.html | 31 | ||||
| -rw-r--r-- | src/Types.hx | 1 | ||||
| -rw-r--r-- | src/server/HttpServer.hx | 87 |
8 files changed, 256 insertions, 276 deletions
diff --git a/default-config.json b/default-config.json index bdfdb4e..afe50c2 100644 --- a/default-config.json +++ b/default-config.json @@ -1,84 +1,55 @@ { - "port": 4200, - "channelName": "SyncTube", - "maxLoginLength": 20, - "maxMessageLength": 500, - "serverChatHistory": 50, - "totalVideoLimit": 0, - "userVideoLimit": 0, - "requestLeaderOnPause": false, - "unpauseWithoutLeader": false, - "localAdmins": true, - "allowProxyIps": true, - "localNetworkOnly": false, - "sslKeyPemPath": "", - "sslCertPemPath": "", - "templateUrl": "https://youtube.com/playlist?list=PL9FiZUDVMu9tc_85frYognMOVFC_-VkSX", - "youtubeApiKey": "AIzaSyDTk1OPRI9cDkAK_BKsBcv10DQCHse-QaA", - "youtubePlaylistLimit": 50, - "cacheStorageLimitGiB": 3.0, - "permissions": { - "banned": [], - "guest": ["writeChat", "addVideo", "removeVideo", "changeOrder", "toggleItemType", "requestLeader", "rewind"], - "user": ["guest"], - "leader": ["user"], - "admin": ["user", "clearChat", "setLeader", "lockPlaylist", "banClient"] - }, - "ytDlp": { - "channel": "stable", - "jsRuntime": "node" - }, - "emotes": [ - {"name": ":adorable:", "image": "https://i.imgur.com/5GxNwDY.png"}, - {"name": ":angry:", "image": "https://i.imgur.com/Mx9lhMZ.png"}, - {"name": ":artist:", "image": "https://i.imgur.com/8wQxnse.png"}, - {"name": ":back:", "image": "https://i.imgur.com/hafcTP1.png"}, - {"name": ":beaten:", "image": "https://i.imgur.com/QIvPD83.png"}, - {"name": ":cold:", "image": "https://i.imgur.com/fwgJPJ2.png"}, - {"name": ":confusion:", "image": "https://i.imgur.com/rQHCTPI.png"}, - {"name": ":doh:", "image": "https://i.imgur.com/EaFIosT.png"}, - {"name": ":drink:", "image": "https://i.imgur.com/mSeXSIk.png"}, - {"name": ":eh:", "image": "https://i.imgur.com/lrpyuCX.png"}, - {"name": ":ehehe:", "image": "https://i.imgur.com/UrxypoB.png"}, - {"name": ":fallen:", "image": "https://i.imgur.com/ihYXAlM.png"}, - {"name": ":frustrated:", "image": "https://i.imgur.com/pSY67Ja.gif"}, - {"name": ":goodmood:", "image": "https://i.imgur.com/t5WgyL6.gif"}, - {"name": ":happy:", "image": "https://i.imgur.com/2JNBCk7.png"}, - {"name": ":hmm:", "image": "https://i.imgur.com/u0O7xrc.png"}, - {"name": ":honor:", "image": "https://i.imgur.com/Dkn7JfX.png"}, - {"name": ":hot:", "image": "https://i.imgur.com/9IHCj1a.png"}, - {"name": ":hungry:", "image": "https://i.imgur.com/QoVVKYK.png"}, - {"name": ":idea:", "image": "https://i.imgur.com/l3HoqtG.png"}, - {"name": ":ill:", "image": "https://i.imgur.com/EgY26B0.png"}, - {"name": ":awesome:", "image": "https://i.imgur.com/3COHK8w.png"}, - {"name": ":lovebreak:", "image": "https://i.imgur.com/FcTCnCx.png"}, - {"name": ":loveformoney:", "image": "https://i.imgur.com/Z18e5NZ.png"}, - {"name": ":money:", "image": "https://i.imgur.com/1uM0wky.png"}, - {"name": ":nani:", "image": "https://i.imgur.com/bePPNni.png"}, - {"name": ":ok:", "image": "https://i.imgur.com/gub2TDR.png"}, - {"name": ":ontheway:", "image": "https://i.imgur.com/fWWBeBz.png"}, - {"name": ":romantic:", "image": "https://i.imgur.com/sze1iiu.png"}, - {"name": ":sad:", "image": "https://i.imgur.com/yAjo1kC.png"}, - {"name": ":scared:", "image": "https://i.imgur.com/rsqs0fw.png"}, - {"name": ":sleep:", "image": "https://i.imgur.com/UbR9xv3.png"}, - {"name": ":think:", "image": "https://i.imgur.com/nAoKYYi.png"}, - {"name": ":tired:", "image": "https://i.imgur.com/mKCmaIQ.png"}, - {"name": ":tricky:", "image": "https://i.imgur.com/gC7NlqY.png"}, - {"name": ":writer:", "image": "https://i.imgur.com/rJLs4Ig.png"}, - {"name": ":haxe:", "image": "https://i.imgur.com/F9Tllyv.png"} - ], - "filters": [ - { - "name": "image", - "regex": "(https?:\\/\\/[^']*\\.)(png|jpg|gif|jpeg|webp)([^' ,]*)", - "flags": "g", - "replace": "<a href='$1$2$3' target='_blank' rel='noopener noreferrer'><img src='$1$2$3' class='chat-img'/></a>" - }, - { - "name": "url", - "regex": "(^|[^'])(https?:\\/\\/[^' \t]*)", - "flags": "g", - "replace": "$1<a href='$2' target='_blank' rel='noopener noreferrer'>$2</a>" - } - ] + "port": 4200, + "channelName": "Dohee Cinema", + "gatePassword": "changeme", + "maxLoginLength": 20, + "maxMessageLength": 500, + "serverChatHistory": 50, + "totalVideoLimit": 0, + "userVideoLimit": 0, + "requestLeaderOnPause": false, + "unpauseWithoutLeader": false, + "localAdmins": true, + "allowProxyIps": true, + "localNetworkOnly": false, + "sslKeyPemPath": "", + "sslCertPemPath": "", + "templateUrl": "YouTube Playlist URL here", + "youtubeApiKey": "", + "youtubePlaylistLimit": 50, + "cacheStorageLimitGiB": 3.0, + "permissions": { + "banned": [], + "guest": [ + "writeChat", + "addVideo", + "removeVideo", + "changeOrder", + "toggleItemType", + "requestLeader", + "rewind" + ], + "user": ["guest"], + "leader": ["user"], + "admin": ["user", "clearChat", "setLeader", "lockPlaylist", "banClient"] + }, + "ytDlp": { + "channel": "stable", + "jsRuntime": "node" + }, + "emotes": [{ "name": ":haxe:", "image": "https://i.imgur.com/F9Tllyv.png" }], + "filters": [ + { + "name": "image", + "regex": "(https?:\\/\\/[^']*\\.)(png|jpg|gif|jpeg|webp)([^' ,]*)", + "flags": "g", + "replace": "<a href='$1$2$3' target='_blank' rel='noopener noreferrer'><img src='$1$2$3' class='chat-img'/></a>" + }, + { + "name": "url", + "regex": "(^|[^'])(https?:\\/\\/[^' \t]*)", + "flags": "g", + "replace": "$1<a href='$2' target='_blank' rel='noopener noreferrer'>$2</a>" + } + ] } diff --git a/res/css/setup.css b/res/css/setup.css index 9755ad3..b42f8a8 100644 --- a/res/css/setup.css +++ b/res/css/setup.css @@ -3,23 +3,42 @@ body { height: 100vh; align-items: center; justify-content: center; + background-color: var(--background-video); + margin: 0; } .setup { margin: auto; - padding: 2rem; - width: 320px; + padding: 2.5rem 2rem; + width: 360px; display: flex; flex-direction: column; align-items: center; - - /* debug */ background-color: #1a1a1f; + color: var(--foreground); + border: 1px solid var(--border); + border-radius: 0.5rem; + gap: 1rem; +} + +.welcome-image { + max-width: 200px; + width: 100%; border-radius: 0.375rem; + margin-bottom: 0.5rem; +} - & h1 { - font-size: 1.75rem; - } +.setup-title { + font-size: 1.75rem; + margin: 0; + text-align: center; +} + +.setup p { + margin: 0; + text-align: center; + opacity: 0.7; + font-size: 0.95rem; } .setup-form { @@ -27,13 +46,23 @@ body { flex-direction: column; gap: 1rem; width: 100%; + margin-top: 0.5rem; + + & input { + width: 100%; + box-sizing: border-box; + } & button { margin: 0; - padding: .75rem .5rem; + padding: 0.75rem 0.5rem; justify-content: center; background-color: var(--accent); color: #fff; + border: none; + border-radius: 0.375rem; + cursor: pointer; + font-size: 0.95rem; &:hover { filter: brightness(1.15); @@ -46,4 +75,5 @@ body { flex-direction: column; gap: 0.5rem; color: var(--error); -} + font-size: 0.9rem; +}
\ No newline at end of file diff --git a/res/img/welcome.webp b/res/img/welcome.webp Binary files differnew file mode 100644 index 0000000..b53f48e --- /dev/null +++ b/res/img/welcome.webp diff --git a/res/index.html b/res/index.html index 2f620c6..dbdde80 100644 --- a/res/index.html +++ b/res/index.html @@ -145,7 +145,7 @@ </section> <!-- Footer --> <footer id="footer"> - <p>Powered by <a href="https://github.com/RblSb/SyncTube" target="_blank" rel="noreferrer noopener">SyncTube</a> + <p>Dohee Cinema is powered by <a href="https://github.com/RblSb/SyncTube" target="_blank" rel="noreferrer noopener">SyncTube</a> </p> </footer> </main> diff --git a/res/langs/en.json b/res/langs/en.json index a7ce267..91d7135 100644 --- a/res/langs/en.json +++ b/res/langs/en.json @@ -1,119 +1,119 @@ { - "connection": "Connection", - "msgConnected": "Connected", - "msgDisconnected": "Disconnected", - "joined": "joined", - "online": "online", - "nothingPlaying": "Nothing Playing", - "hintListStart": "Welcome to SyncTube! Here you can:", - "hintListAddVideo": "$addVideos to watch together", - "hintListRequestLeader": "$requestLeader to pause and rewind videos for everyone", - "hintListRequestLeaderMouse": "(also use right mouse button for quick pause)", - "hintListRequestLeaderTouch": "(also use long tap for quick pause)", - "hintListOpenInApp": "$openInApp this server for better Android experience", - "hintListHide": "$hideThisMessage and send <code>/help</code> in chat to see it again", - "addVideos": "Add Videos", - "requestLeader": "Request Leader", - "openInApp": "Open in App", - "hideThisMessage": "Hide this message", - "usernameError": "Username length must be from 1 to $MAX characters and don't repeat another's. Characters &^<>'\" are not allowed.", - "passwordError": "Password length must be from $MIN to $MAX characters.", - "passwordsMismatchError": "Passwords do not match.", - "passwordMatchError": "Wrong password.", - "accessError": "Access error", - "noPermission": "No '$PERMISSION' permission.", - "totalVideoLimitError": "Playlist video limit has been reached.", - "userVideoLimitError": "Playlist video limit per user has been reached.", - "videoAlreadyExistsError": "The video already exists in playlist.", - "addVideoError": "Failed to add video.", - "adminsCannotBeBannedError": "Admins cannot be banned. Remove them first.", - "caching": "Caching", - "downloading": "Downloading", - "uploading": "Uploading", - "rawVideo": "Raw video", - "videos": "videos", - "addedBy": "Added by", - "play": "Play", - "setNext": "Next", - "makePermanent": "Make Permanent", - "makeTemporary": "Make Temporary", - "delete": "Delete", - "account": "Account", - "exportSettings": "Export Settings", - "importSettings": "Import Settings", - "login": "Login", - "exit": "Exit", - "settings": "Settings", - "synchThreshold": "Synch Threshold", - "general": "General", - "hotkeys": "Hotkeys", - "video": "Video", - "channel": "Channel", - "layout": "Layout", - "swapLayout": "Swap Layout", - "chatOnly": "Chat Only", - "setVideoUrl": "Set Video URL", - "setVideoUrlPrompt": "New video URL:\n(Does not affect other users)", - "selectLocalVideo": "Select Local Video", - "removePlayer": "Remove Player", - "restorePlayer": "Restore Player", - "toggleUserList": "Show/Hide Userlist", - "leaderDesc": "Request video control permissions", - "mobileViewBtn": "Mobile View", - "leader": "Leader", - "enterAsGuest": "Enter As Guest:", - "yourName": "Your Name", - "enterUserPassword": "Enter User Password", - "yourPassword": "Your Password", - "emotes": "Emotes", - "chat": "Chat", - "kicked": "Kicked", - "clearChat": "Clear Chat", - "chatlinePlaceholder": "Send a message...", - "leaderDisconnectedServerOnPause": "Leader was disconnected, server on pause.", - "unpause": "Unpause", - "addVideoFromUrl": "Add video from URL", - "embedCustomFrame": "Embed a custom frame", - "clearPlaylist": "Clear playlist", - "shufflePlaylist": "Shuffle playlist", - "playlist": "Playlist", - "playlistOpen": "Playlist open", - "playlistLocked": "Playlist locked", - "expandPlayer": "Expand player", - "toggleVideoSync": "Toggle video synchronization", - "toggleSynchConfirm": "Are you sure you want to turn off video sync?", - "refreshPlayer": "Refresh player", - "fullscreenPlayer": "Fullscreen player", - "retrievePlaylistLinks": "Retrieve playlist links", - "voteForSkip": "Vote for skip", - "addAsTemporary": "Add as temporary", - "cacheOnServer": "Cache on server", - "mediaUrl": "Media URL", - "optionalTitle": "Title (optional)", - "subtitlesUrlOptional": "Subtitles URL (optional)", - "voiceOverAudioTrackUrlOptional": "Voice-over audio URL (optional)", - "addTemplateUrl": "Add template URL", - "queueNext": "Queue next", - "queueLast": "Queue last", - "and": "and", - "or": "or", - "to": "to", - "pasteEmbedCodeAndClick": "Paste the embed code here", - "acceptableEmbedCodesAre": "Acceptable embed codes are", - "customEmbedsCannotBeSynchronized": "CUSTOM EMBEDS CANNOT BE SYNCHRONIZED", - "save": "Save", - "skipItemConfirm": "Are you sure you want to skip current video?", - "clearPlaylistConfirm": "Are you sure you want to clear the playlist?", - "shufflePlaylistConfirm": "Are you sure you want to shuffle the playlist?", - "lockPlaylistConfirm": "Are you sure you want to lock the playlist?", + "connection": "Connection", + "msgConnected": "Connected", + "msgDisconnected": "Disconnected", + "joined": "joined", + "online": "online", + "nothingPlaying": "Nothing Playing", + "hintListStart": "Welcome to Dohee Cinema! Here you can:", + "hintListAddVideo": "$addVideos to watch together (press the + button)", + "hintListRequestLeader": "$requestLeader to pause and rewind videos for everyone", + "hintListRequestLeaderMouse": "(also use right mouse button for quick pause)", + "hintListRequestLeaderTouch": "(also use long tap for quick pause)", + "hintListOpenInApp": "$openInApp this server for better Android experience", + "hintListHide": "$hideThisMessage and send <code>/help</code> in chat to see it again", + "addVideos": "Add Videos", + "requestLeader": "Request Leader", + "openInApp": "Open in App", + "hideThisMessage": "Hide this message", + "usernameError": "Username length must be from 1 to $MAX characters and don't repeat another's. Characters &^<>'\" are not allowed.", + "passwordError": "Password length must be from $MIN to $MAX characters.", + "passwordsMismatchError": "Passwords do not match.", + "passwordMatchError": "Wrong password.", + "accessError": "Access error", + "noPermission": "No '$PERMISSION' permission.", + "totalVideoLimitError": "Playlist video limit has been reached.", + "userVideoLimitError": "Playlist video limit per user has been reached.", + "videoAlreadyExistsError": "The video already exists in playlist.", + "addVideoError": "Failed to add video.", + "adminsCannotBeBannedError": "Admins cannot be banned. Remove them first.", + "caching": "Caching", + "downloading": "Downloading", + "uploading": "Uploading", + "rawVideo": "Raw video", + "videos": "videos", + "addedBy": "Added by", + "play": "Play", + "setNext": "Next", + "makePermanent": "Make Permanent", + "makeTemporary": "Make Temporary", + "delete": "Delete", + "account": "Account", + "exportSettings": "Export Settings", + "importSettings": "Import Settings", + "login": "Login", + "exit": "Exit", + "settings": "Settings", + "synchThreshold": "Synch Threshold", + "general": "General", + "hotkeys": "Hotkeys", + "video": "Video", + "channel": "Channel", + "layout": "Layout", + "swapLayout": "Swap Layout", + "chatOnly": "Chat Only", + "setVideoUrl": "Set Video URL", + "setVideoUrlPrompt": "New video URL:\n(Does not affect other users)", + "selectLocalVideo": "Select Local Video", + "removePlayer": "Remove Player", + "restorePlayer": "Restore Player", + "toggleUserList": "Show/Hide Userlist", + "leaderDesc": "Request video control permissions", + "mobileViewBtn": "Mobile View", + "leader": "Leader", + "enterAsGuest": "Enter As Guest:", + "yourName": "Your Name", + "enterUserPassword": "Enter User Password", + "yourPassword": "Your Password", + "emotes": "Emotes", + "chat": "Chat", + "kicked": "Kicked", + "clearChat": "Clear Chat", + "chatlinePlaceholder": "Send a message...", + "leaderDisconnectedServerOnPause": "Leader was disconnected, server on pause.", + "unpause": "Unpause", + "addVideoFromUrl": "Add video from URL", + "embedCustomFrame": "Embed a custom frame", + "clearPlaylist": "Clear playlist", + "shufflePlaylist": "Shuffle playlist", + "playlist": "Playlist", + "playlistOpen": "Playlist open", + "playlistLocked": "Playlist locked", + "expandPlayer": "Expand player", + "toggleVideoSync": "Toggle video synchronization", + "toggleSynchConfirm": "Are you sure you want to turn off video sync?", + "refreshPlayer": "Refresh player", + "fullscreenPlayer": "Fullscreen player", + "retrievePlaylistLinks": "Retrieve playlist links", + "voteForSkip": "Vote for skip", + "addAsTemporary": "Add as temporary", + "cacheOnServer": "Cache on server", + "mediaUrl": "Media URL", + "optionalTitle": "Title (optional)", + "subtitlesUrlOptional": "Subtitles URL (optional)", + "voiceOverAudioTrackUrlOptional": "Voice-over audio URL (optional)", + "addTemplateUrl": "Add template URL", + "queueNext": "Queue next", + "queueLast": "Queue last", + "and": "and", + "or": "or", + "to": "to", + "pasteEmbedCodeAndClick": "Paste the embed code here", + "acceptableEmbedCodesAre": "Acceptable embed codes are", + "customEmbedsCannotBeSynchronized": "CUSTOM EMBEDS CANNOT BE SYNCHRONIZED", + "save": "Save", + "skipItemConfirm": "Are you sure you want to skip current video?", + "clearPlaylistConfirm": "Are you sure you want to clear the playlist?", + "shufflePlaylistConfirm": "Are you sure you want to shuffle the playlist?", + "lockPlaylistConfirm": "Are you sure you want to lock the playlist?", - "yes": "Yes", - "no": "No", - "on": "On", - "off": "Off", + "yes": "Yes", + "no": "No", + "on": "On", + "off": "Off", - "areYouSure": "Are you sure?", - "dataWillBeLost": "The data will be lost.", + "areYouSure": "Are you sure?", + "dataWillBeLost": "The data will be lost.", - "setupTitle": "Welcome to SyncTube!" + "setupTitle": "Welcome to Dohee Cinema!" } diff --git a/res/setup.html b/res/setup.html index 8068a9d..546ee1b 100644 --- a/res/setup.html +++ b/res/setup.html @@ -19,17 +19,16 @@ <body> <main class="setup"> - <h1 class="setup-title">SyncTube</h1> - <p>Create your admin account</p> + <img class="welcome-image" src="img/welcome.webp" alt="Welcome to Dohee Cinema"> + <h1 class="setup-title">Welcome to the Dohee Cinema</h1> + <p>put in the password for entry</p> - <form id="setup-form" class="setup-form" action="/setup" method="POST"> - <input type="text" name="name" placeholder="Name"> + <form id="setup-form" class="setup-form"> <input type="password" name="password" placeholder="Password"> - <input type="password" name="confirmation" placeholder="Repeat password"> <div id="form-errors" class="form-errors"></div> - <button type="submit">Create</button> + <button type="submit">Enter</button> </form> </main> @@ -40,30 +39,24 @@ formElement.addEventListener("submit", function (e) { e.preventDefault(); - const { name, password, confirmation } = formElement.elements; + const { password } = formElement.elements; const payload = { - name: name.value, password: password.value, - passwordConfirmation: confirmation.value, - } + }; - fetch("/setup", { method: "POST", body: JSON.stringify(payload) }) + fetch("/gate", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }) .then(res => res.json()) .then(response => handleResponse(response)) .catch(() => handleResponse(null)); }, true); - function handleResponse(response) { - if (response.success) { - return window.location.reload(); + if (response && response.success === true) { + window.location.href = "/"; + return; } - const errors = !response - ? ["Unknown error"] - : (response.errors ?? []).map(item => item.error); - - showErrors(errorsElement, errors); + showErrors(errorsElement, ["Incorrect password. Not cool man"]); } function showErrors(container, errors) { diff --git a/src/Types.hx b/src/Types.hx index 22b6ec2..6fbe55b 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -31,6 +31,7 @@ typedef VideoData = { typedef ServerConfig = Config & { serverChatHistory:Int, + gatePassword:String, localAdmins:Bool, allowProxyIps:Bool, localNetworkOnly:Bool, diff --git a/src/server/HttpServer.hx b/src/server/HttpServer.hx index f7c6d8c..5917ee0 100644 --- a/src/server/HttpServer.hx +++ b/src/server/HttpServer.hx @@ -1,6 +1,7 @@ package server; import Types.UploadResponse; +import haxe.crypto.Sha256; import haxe.io.Path; import js.node.Buffer; import js.node.Fs.Fs; @@ -24,10 +25,8 @@ private class HttpServerConfig { public final cache:Cache = null; } -typedef SetupAdminRequest = { - name:String, +typedef GateRequest = { password:String, - passwordConfirmation:String, } class HttpServer { @@ -100,8 +99,8 @@ class HttpServer { } } switch url.pathname { - case "/setup": - finishSetup(req, res); + case "/gate": + verifyGate(req, res); } return; } @@ -121,8 +120,8 @@ class HttpServer { return; } - if (url.pathname == "/setup") { - if (main.hasAdmins()) { + if (url.pathname == "/gate") { + if (!hasGatePassword() || hasValidGateCookie(req)) { res.redirect("/"); return; } @@ -158,8 +157,8 @@ class HttpServer { } if (ext == "html") { - if (!main.isNoState && !main.hasAdmins()) { - res.redirect("/setup"); + if (hasGatePassword() && !hasValidGateCookie(req)) { + res.redirect("/gate"); return; } // replace ${textId} to localized strings @@ -244,8 +243,8 @@ class HttpServer { }); } - function finishSetup(req:IncomingMessage, res:ServerResponse) { - if (main.hasAdmins()) { + function verifyGate(req:IncomingMessage, res:ServerResponse) { + if (!hasGatePassword()) { return res.redirect("/"); } @@ -257,55 +256,41 @@ class HttpServer { req.on("end", () -> { final body = Buffer.concat(bodyChunks).toString(); - final jsonParser = new JsonParser<SetupAdminRequest>(); + final jsonParser = new JsonParser<GateRequest>(); final jsonData = jsonParser.fromJson(body); if (jsonParser.errors.length > 0) { - final errors = ErrorUtils.convertErrorArray(jsonParser.errors); - trace(errors); - res.status(400).json({success: false, errors: []}); + res.status(400).json({success: false}); return; } - final name = jsonData.name; final password = jsonData.password; - final passwordConfirmation = jsonData.passwordConfirmation; - final lang = req.headers["accept-language"] ?? "en"; - final errors:Array<{type:String, error:String}> = []; - - if (main.isBadClientName(name)) { - final error = Lang.get(lang, "usernameError") - .replace("$MAX", '${main.config.maxLoginLength}'); - errors.push({ - type: "name", - error: error - }); - } - - final min = Main.MIN_PASSWORD_LENGTH; - final max = Main.MAX_PASSWORD_LENGTH; - if (password.length < min || password.length > max) { - final error = Lang.get(lang, "passwordError") - .replace("$MIN", '$min').replace("$MAX", '$max'); - errors.push({ - type: "password", - error: error - }); + if (password == main.config.gatePassword) { + final token = getGateToken(); + res.setHeader("set-cookie", 'gate_auth=$token; Path=/; HttpOnly; SameSite=Strict'); + res.status(200).json({success: true}); + } else { + res.status(401).json({success: false}); } + }); + } - if (password != passwordConfirmation) { - errors.push({ - type: "password", - error: Lang.get(lang, "passwordsMismatchError") - }); - } + function hasGatePassword():Bool { + final gp = main.config.gatePassword; + return gp != null && gp.length > 0; + } - if (errors.length > 0) { - res.status(400).json({success: false, errors: errors}); - return; - } + function hasValidGateCookie(req:IncomingMessage):Bool { + final cookieHeader:String = req.headers["cookie"]; + if (cookieHeader == null) return false; + final token = getGateToken(); + final needle = 'gate_auth=$token'; + for (cookie in cookieHeader.split(";")) { + if (cookie.trim() == needle) return true; + } + return false; + } - main.addAdmin(name, password); - res.status(200).json({success: true}); - }); + function getGateToken():String { + return Sha256.encode('gate_${main.config.gatePassword}_${main.config.salt}'); } function getPath(dir:String, url:URL):String { |
