generated from azures04/Base-REST-API
Add auth, JWT tokens, and bootstrap startup
Introduce bootstrap entrypoint and prestartup to ping DB and generate/manage RSA keypair. Add security module for key IO. Implement JWT-based access and refresh tokens (tokensService) with refresh_tokens table and repo. Add auth, provider and user services, and refresh-token management. Update repositories (users, credentials, providers, servers) with SQL fixes and new helper methods. Move DDL execution to bootstrap (remove from server). Update package.json main and add dependencies (bcryptjs, jsonwebtoken). Update .env.example and .gitignore accordingly.
This commit is contained in:
@@ -3,7 +3,7 @@ const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function findByUserId(userId) {
|
||||
try {
|
||||
const sql = "SELECT* FROM credentials WHERE userId = ?"
|
||||
const sql = "SELECT * FROM credentials WHERE userId = ?"
|
||||
const rows = await pool.query(sql, [userId])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
@@ -11,20 +11,20 @@ async function findByUserId(userId) {
|
||||
}
|
||||
}
|
||||
|
||||
async function create(userId, hashedPassword) {
|
||||
async function create(userId, passwordHash) {
|
||||
try {
|
||||
const sql = "INSERT INTO credentials (userId, hashedPassword) VALUES (?, ?)"
|
||||
const rows = await pool.query(sql, [userId, hashedPassword])
|
||||
return rows[0] || null
|
||||
const sql = "INSERT INTO credentials (userId, passwordHash) VALUES (?, ?)"
|
||||
const rows = await pool.query(sql, [userId, passwordHash])
|
||||
return rows || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function updatePassword(userId, hashedPassword) {
|
||||
async function updatePassword(userId, passwordHash) {
|
||||
try {
|
||||
const sql = "UPDATE credentials SET hashedPassword = ? WHERE userId = ?"
|
||||
const rows = await pool.query(sql, [hashedPassword, userId])
|
||||
const sql = "UPDATE credentials SET passwordHash = ? WHERE userId = ?"
|
||||
const rows = await pool.query(sql, [passwordHash, userId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
|
||||
@@ -3,7 +3,7 @@ const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function findByUserId(userId) {
|
||||
try {
|
||||
const sql = "SELECT* FROM identities WHERE userId = ?"
|
||||
const sql = "SELECT * FROM identities WHERE userId = ?"
|
||||
const rows = await pool.query(sql, [userId])
|
||||
return rows || null
|
||||
} catch (error) {
|
||||
@@ -13,7 +13,7 @@ async function findByUserId(userId) {
|
||||
|
||||
async function findByProviderAndSubject(providerId, providerUserId) {
|
||||
try {
|
||||
const sql = "SELECT* FROM identities WHERE providerId = ? AND providerUserId = ?"
|
||||
const sql = "SELECT * FROM identities WHERE providerId = ? AND providerUserId = ?"
|
||||
const rows = await pool.query(sql, [providerId, providerUserId])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
|
||||
@@ -3,7 +3,7 @@ const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function findById(id) {
|
||||
try {
|
||||
const sql = "SELECT* FROM providers WHERE id = ?"
|
||||
const sql = "SELECT * FROM providers WHERE id = ?"
|
||||
const rows = await pool.query(sql, [id])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
@@ -13,7 +13,7 @@ async function findById(id) {
|
||||
|
||||
async function findByName(id) {
|
||||
try {
|
||||
const sql = "SELECT* FROM providers WHERE name = ?"
|
||||
const sql = "SELECT * FROM providers WHERE name = ?"
|
||||
const rows = await pool.query(sql, [id])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
@@ -23,7 +23,7 @@ async function findByName(id) {
|
||||
|
||||
async function listEnabled() {
|
||||
try {
|
||||
const sql = "SELECT* FROM providers WHERE isEnabled = ?"
|
||||
const sql = "SELECT * FROM providers WHERE isEnabled = ?"
|
||||
const rows = await pool.query(sql, [true])
|
||||
return rows || []
|
||||
} catch (error) {
|
||||
@@ -31,6 +31,16 @@ async function listEnabled() {
|
||||
}
|
||||
}
|
||||
|
||||
async function listAll() {
|
||||
try {
|
||||
const sql = "SELECT * FROM providers"
|
||||
const rows = await pool.query(sql)
|
||||
return rows || []
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function setEnabled(id, isEnabled) {
|
||||
try {
|
||||
const sql = "UPDATE providers SET isEnabled = ? WHERE id = ?"
|
||||
@@ -97,6 +107,7 @@ async function remove(id) {
|
||||
module.exports = {
|
||||
remove,
|
||||
create,
|
||||
listAll,
|
||||
findById,
|
||||
findByName,
|
||||
setEnabled,
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
const { pool } = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function create(userId, tokenHash, expiresAt) {
|
||||
try {
|
||||
const sql = "INSERT INTO refresh_tokens (userId, tokenHash, expiresAt) VALUES (?, ?, ?)"
|
||||
const rows = await pool.query(sql, [userId, tokenHash, expiresAt])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findByTokenHash(tokenHash) {
|
||||
try {
|
||||
const sql = "SELECT * FROM refresh_tokens WHERE tokenHash = ?"
|
||||
const rows = await pool.query(sql, [tokenHash])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findByUserId(userId) {
|
||||
try {
|
||||
const sql = "SELECT * FROM refresh_tokens WHERE userId = ?"
|
||||
const rows = await pool.query(sql, [userId])
|
||||
return rows[0] || []
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function removeByTokenHash(tokenHash) {
|
||||
try {
|
||||
const sql = "DELETE FROM refresh_tokens WHERE tokenHash = ?"
|
||||
const rows = await pool.query(sql, [tokenHash])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function removeByUserId(userId) {
|
||||
try {
|
||||
const sql = "DELETE FROM refresh_tokens WHERE userId = ?"
|
||||
const rows = await pool.query(sql, [userId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function removeExpired() {
|
||||
try {
|
||||
const sql = "DELETE FROM refresh_tokens WHERE expiresAt < NOW()"
|
||||
const rows = await pool.query(sql)
|
||||
return rows.affectedRows
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
create,
|
||||
findByTokenHash,
|
||||
findByUserId,
|
||||
removeByTokenHash,
|
||||
removeByUserId,
|
||||
removeExpired,
|
||||
}
|
||||
@@ -3,7 +3,7 @@ const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function findById(id) {
|
||||
try {
|
||||
const sql = "SELECT* FROM servers WHERE id = ?"
|
||||
const sql = "SELECT * FROM servers WHERE id = ?"
|
||||
const rows = await pool.query(sql, [id])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
@@ -13,7 +13,7 @@ async function findById(id) {
|
||||
|
||||
async function findByUrl(url) {
|
||||
try {
|
||||
const sql = "SELECT* FROM servers WHERE url = ?"
|
||||
const sql = "SELECT * FROM servers WHERE url = ?"
|
||||
const rows = await pool.query(sql, [url])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
@@ -31,6 +31,16 @@ async function create(url, publicKey) {
|
||||
}
|
||||
}
|
||||
|
||||
async function createAndAssignIdManually(id, url, publicKey) {
|
||||
try {
|
||||
const sql = "INSERT INTO servers (id, serverUrl, publicKey) VALUES (?, ?, ?)"
|
||||
const rows = await pool.query(sql, [id, url, publicKey])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function remove(id) {
|
||||
try {
|
||||
const sql = "DELETE FROM servers WHERE id = ?"
|
||||
@@ -74,5 +84,6 @@ module.exports = {
|
||||
remove,
|
||||
findById,
|
||||
findByUrl,
|
||||
updateServer
|
||||
updateServer,
|
||||
createAndAssignIdManually
|
||||
}
|
||||
@@ -3,7 +3,7 @@ const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function findById(id) {
|
||||
try {
|
||||
const sql = "SELECT* FROM servers WHERE id = ?"
|
||||
const sql = "SELECT * FROM users WHERE id = ?"
|
||||
const rows = await pool.query(sql, [id])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
@@ -11,16 +11,29 @@ async function findById(id) {
|
||||
}
|
||||
}
|
||||
|
||||
async function create(serverId, remoteId = null, displayName, avatarUrl) {
|
||||
async function findByIdentifier(identifier) {
|
||||
try {
|
||||
const sql = "INSERT INTO users (serverId, remoteId, displayName, avatarUrl) VALUES (?, ?, ?, ?)"
|
||||
const rows = await pool.query(sql, [serverId, remoteId, displayName, avatarUrl])
|
||||
const sql = "SELECT * FROM users WHERE identifier = ?"
|
||||
const rows = await pool.query(sql, [identifier])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function create(identifier, serverId, remoteId = null, displayName, avatarUrl) {
|
||||
try {
|
||||
const sql = "INSERT INTO users (identifier, serverId, remoteId, displayName, avatarUrl) VALUES (?, ?, ?, ?, ?) RETURNING *"
|
||||
const rows = await pool.query(sql, [identifier, serverId, remoteId, displayName, avatarUrl])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
if (error.code && error.code == "ER_DUP_ENTRY") {
|
||||
throw new DefaultError(401, "Identifier already taken.", "Identifier already assigned.")
|
||||
}
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function remove(id) {
|
||||
try {
|
||||
const sql = "DELETE FROM users WHERE id = ?"
|
||||
@@ -86,5 +99,6 @@ module.exports = {
|
||||
isLocal,
|
||||
findById,
|
||||
updateProfile,
|
||||
findByIdentifier,
|
||||
findByServerAndRemoteId
|
||||
}
|
||||
Reference in New Issue
Block a user