feat: init project with miniprogram, cloud functions and admin console
这个提交包含在:
@@ -0,0 +1,62 @@
|
||||
var jwt = require('jsonwebtoken')
|
||||
|
||||
var JWT_SECRET = process.env.JWT_SECRET || 'hox_jwt_secret_change_in_production'
|
||||
var JWT_EXPIRES_IN = '7d'
|
||||
|
||||
function generateToken(userId, openid) {
|
||||
return jwt.sign(
|
||||
{ user_id: userId, openid: openid },
|
||||
JWT_SECRET,
|
||||
{ expiresIn: JWT_EXPIRES_IN }
|
||||
)
|
||||
}
|
||||
|
||||
function verifyToken(token) {
|
||||
try {
|
||||
return jwt.verify(token, JWT_SECRET)
|
||||
} catch (e) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function generateAdminToken(adminId, username, role) {
|
||||
return jwt.sign(
|
||||
{ admin_id: adminId, username: username, role: role, type: 'admin' },
|
||||
JWT_SECRET,
|
||||
{ expiresIn: JWT_EXPIRES_IN }
|
||||
)
|
||||
}
|
||||
|
||||
function extractToken(event) {
|
||||
var header = event.headers || {}
|
||||
var auth = header['Authorization'] || header['authorization'] || header['authorization'] || ''
|
||||
if (auth.startsWith('Bearer ')) {
|
||||
return auth.substring(7)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function extractUser(event) {
|
||||
var token = extractToken(event)
|
||||
if (!token) return null
|
||||
var decoded = verifyToken(token)
|
||||
if (!decoded || decoded.type === 'admin') return null
|
||||
return decoded
|
||||
}
|
||||
|
||||
function extractAdmin(event) {
|
||||
var token = extractToken(event)
|
||||
if (!token) return null
|
||||
var decoded = verifyToken(token)
|
||||
if (!decoded || decoded.type !== 'admin') return null
|
||||
return decoded
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
generateToken: generateToken,
|
||||
verifyToken: verifyToken,
|
||||
generateAdminToken: generateAdminToken,
|
||||
extractToken: extractToken,
|
||||
extractUser: extractUser,
|
||||
extractAdmin: extractAdmin
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
var mysql = require('mysql2/promise')
|
||||
|
||||
var pool = null
|
||||
|
||||
function getPool() {
|
||||
if (pool) return pool
|
||||
|
||||
pool = mysql.createPool({
|
||||
host: process.env.DB_HOST || 'localhost',
|
||||
port: parseInt(process.env.DB_PORT || '3306'),
|
||||
user: process.env.DB_USER || 'root',
|
||||
password: process.env.DB_PASSWORD || '',
|
||||
database: process.env.DB_NAME || 'hox',
|
||||
waitForConnections: true,
|
||||
connectionLimit: 10,
|
||||
charset: 'utf8mb4'
|
||||
})
|
||||
|
||||
return pool
|
||||
}
|
||||
|
||||
async function query(sql, params) {
|
||||
var p = getPool()
|
||||
var [rows] = await p.execute(sql, params)
|
||||
return rows
|
||||
}
|
||||
|
||||
async function insert(sql, params) {
|
||||
var p = getPool()
|
||||
var [result] = await p.execute(sql, params)
|
||||
return result
|
||||
}
|
||||
|
||||
async function update(sql, params) {
|
||||
var p = getPool()
|
||||
var [result] = await p.execute(sql, params)
|
||||
return result
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
query: query,
|
||||
insert: insert,
|
||||
update: update,
|
||||
getPool: getPool
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
var db = require('./db')
|
||||
|
||||
async function writeLog(options) {
|
||||
try {
|
||||
await db.insert(
|
||||
'INSERT INTO operation_logs (operator_type, operator_id, target_type, target_id, action, before_snapshot, after_snapshot, ip_address, user_agent, remark) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[
|
||||
options.operator_type || 2,
|
||||
options.operator_id || null,
|
||||
options.target_type || '',
|
||||
options.target_id || null,
|
||||
options.action || '',
|
||||
options.before_snapshot ? JSON.stringify(options.before_snapshot) : null,
|
||||
options.after_snapshot ? JSON.stringify(options.after_snapshot) : null,
|
||||
options.ip_address || null,
|
||||
options.user_agent || null,
|
||||
options.remark || null
|
||||
]
|
||||
)
|
||||
} catch (e) {
|
||||
console.error('writeLog failed:', e.message)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
writeLog: writeLog
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
var RESPONSE = {
|
||||
success: function (data, message) {
|
||||
return {
|
||||
code: 0,
|
||||
message: message || 'success',
|
||||
data: data || null
|
||||
}
|
||||
},
|
||||
error: function (code, message) {
|
||||
return {
|
||||
code: code || -1,
|
||||
message: message || 'error',
|
||||
data: null
|
||||
}
|
||||
},
|
||||
paginate: function (list, total, page, pageSize) {
|
||||
return {
|
||||
code: 0,
|
||||
message: 'success',
|
||||
data: {
|
||||
total: total,
|
||||
page: page,
|
||||
page_size: pageSize,
|
||||
records: list
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ERROR_CODES = {
|
||||
INVALID_TOKEN: { code: 1001, message: 'invalid_token' },
|
||||
TOKEN_EXPIRED: { code: 1002, message: 'token_expired' },
|
||||
PERMISSION_DENIED: { code: 1003, message: 'permission_denied' },
|
||||
USER_NOT_FOUND: { code: 1004, message: 'user_not_found' },
|
||||
DEVICE_NOT_FOUND: { code: 1005, message: 'device_not_found' },
|
||||
DEVICE_NOT_BOUND: { code: 1006, message: 'device_not_bound' },
|
||||
SUBSCRIPTION_REQUIRED: { code: 1007, message: 'subscription_required' },
|
||||
SUBSCRIPTION_EXPIRED: { code: 1008, message: 'subscription_expired' },
|
||||
PARAM_ERROR: { code: 2001, message: 'param_error' },
|
||||
NETWORK_ERROR: { code: 2002, message: 'network_error' },
|
||||
SERVER_ERROR: { code: 3001, message: 'server_error' }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RESPONSE: RESPONSE,
|
||||
ERROR_CODES: ERROR_CODES
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户