cloudtube/utils/getuser.js

132 lines
3.6 KiB
JavaScript
Raw Normal View History

2020-08-30 13:54:59 +00:00
const crypto = require("crypto")
const {parse: parseCookie} = require("cookie")
const constants = require("./constants")
const db = require("./db")
function getToken(req, responseHeaders) {
if (!req.headers.cookie) req.headers.cookie = ""
const cookie = parseCookie(req.headers.cookie)
2020-09-23 11:45:02 +00:00
let token = cookie.token
if (!token) {
if (responseHeaders) { // we should create a token
2021-01-08 12:49:22 +00:00
token = setToken(responseHeaders).token
2020-09-23 11:45:02 +00:00
} else {
return null
}
2020-08-30 13:54:59 +00:00
}
db.prepare(
"INSERT INTO SeenTokens (token, seen) VALUES (?, ?)"
+ " ON CONFLICT (token) DO UPDATE SET seen = excluded.seen"
).run([token, Date.now()])
2020-09-23 11:45:02 +00:00
return token
2020-08-30 13:54:59 +00:00
}
2020-12-29 03:21:48 +00:00
function setToken(responseHeaders, token) {
const setCookie = responseHeaders["set-cookie"] || []
if (!token) token = crypto.randomBytes(18).toString("base64").replace(/\W/g, "_")
setCookie.push(`token=${token}; Path=/; Max-Age=2147483647; HttpOnly; SameSite=Lax`)
2020-12-29 03:21:48 +00:00
responseHeaders["set-cookie"] = setCookie
2021-01-08 12:49:22 +00:00
return {token, responseHeaders}
2020-12-29 03:21:48 +00:00
}
2020-08-30 13:54:59 +00:00
class User {
constructor(token) {
this.token = token
}
2021-05-11 09:27:57 +00:00
/** @return {{instance?: string, save_history?: boolean, local?: boolean, quality?: number}} */
2020-08-31 13:22:16 +00:00
getSettings() {
if (this.token) {
return db.prepare("SELECT * FROM Settings WHERE token = ?").get(this.token) || {}
} else {
return {}
}
}
2021-05-11 09:27:57 +00:00
/** @return {{instance?: string, save_history?: boolean, local?: boolean, quality?: number}} */
2020-08-31 13:22:16 +00:00
getSettingsOrDefaults() {
const settings = this.getSettings()
2020-08-31 13:40:34 +00:00
for (const key of Object.keys(constants.user_settings)) {
if (settings[key] == null) settings[key] = constants.user_settings[key].default
2020-08-31 13:22:16 +00:00
}
return settings
}
2020-08-30 13:54:59 +00:00
getSubscriptions() {
if (this.token) {
2022-01-10 01:18:45 +00:00
return db.prepare("SELECT ucid FROM Subscriptions WHERE token = ?").pluck().all(this.token)
2020-08-30 13:54:59 +00:00
} else {
return []
}
}
isSubscribed(ucid) {
if (this.token) {
2022-01-10 01:18:45 +00:00
return !!db.prepare("SELECT * FROM Subscriptions WHERE token = ? AND ucid = ?").get([this.token, ucid])
2020-08-30 13:54:59 +00:00
} else {
return false
}
}
getWatchedVideos() {
const settings = this.getSettingsOrDefaults()
if (this.token && settings.save_history) {
return db.prepare("SELECT videoID FROM WatchedVideos WHERE token = ?").pluck().all(this.token)
} else {
return []
}
}
addWatchedVideoMaybe(videoID) {
const settings = this.getSettingsOrDefaults()
if (videoID && this.token && settings.save_history) {
db.prepare("INSERT OR IGNORE INTO WatchedVideos (token, videoID) VALUES (?, ?)").run([this.token, videoID])
}
}
2021-05-11 12:29:44 +00:00
getFilters() {
if (this.token) {
return db.prepare("SELECT * FROM Filters WHERE token = ? ORDER BY data ASC").all(this.token)
} else {
return []
}
}
2020-08-30 13:54:59 +00:00
}
/**
2021-01-13 11:55:03 +00:00
* @param {any} [responseHeaders] supply this to create a token
2020-08-30 13:54:59 +00:00
*/
function getUser(req, responseHeaders) {
const token = getToken(req, responseHeaders)
return new User(token)
}
function generateCSRF() {
const token = crypto.randomBytes(16).toString("hex")
const expires = Date.now() + constants.caching.csrf_time
db.prepare("INSERT INTO CSRFTokens (token, expires) VALUES (?, ?)").run(token, expires)
return token
}
function checkCSRF(token) {
const row = db.prepare("SELECT * FROM CSRFTokens WHERE token = ? AND expires > ?").get(token, Date.now())
if (row) {
db.prepare("DELETE FROM CSRFTokens WHERE token = ?").run(token)
return true
} else {
return false
}
}
function cleanCSRF() {
db.prepare("DELETE FROM CSRFTokens WHERE expires <= ?").run(Date.now())
}
cleanCSRF()
setInterval(cleanCSRF, constants.caching.csrf_time).unref()
module.exports.getToken = getToken
2020-12-29 03:21:48 +00:00
module.exports.setToken = setToken
2020-08-30 13:54:59 +00:00
module.exports.generateCSRF = generateCSRF
module.exports.checkCSRF = checkCSRF
module.exports.getUser = getUser