mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-06 03:20:13 +08:00
refactor utils
This commit is contained in:
1 parent
9509bbc355
commit
d6c95cea4a
13 files changed
+126
-31
No files matched your search
@@ -60,6 +60,11 @@ module.exports = {
|
||||
tsx: 'never',
|
||||
},
|
||||
],
|
||||
'lines-between-class-members': [
|
||||
'error',
|
||||
'always',
|
||||
{ exceptAfterSingleLine: true },
|
||||
],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
"app": "yarn workspace app dev",
|
||||
"app:local": "yarn workspace app dev:local",
|
||||
"build": "yarn workspaces foreach -Apt run build",
|
||||
"dev": "yarn workspaces foreach -Rpi --from '{server,app}' run watch",
|
||||
"dev": "yarn workspaces foreach -Api --include '{server,app}' run watch",
|
||||
"server": "yarn workspace server dev",
|
||||
"cli": "yarn workspace client start",
|
||||
"lint": "eslint .",
|
||||
|
||||
@@ -45,8 +45,13 @@
|
||||
"yaml": "^2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/express-session": "^1.17.10",
|
||||
"@types/jsonwebtoken": "^9.0.5",
|
||||
"@types/passport": "^1.0.16",
|
||||
"@types/passport-oauth2": "^1.4.15",
|
||||
"@types/validator": "^13.11.9",
|
||||
"concurrently": "^8.2.2",
|
||||
"jest": "^29.6.1",
|
||||
"nodemon": "^3.0.1",
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
import { User } from '@linux-odyssey/models'
|
||||
import type { Profile } from 'passport'
|
||||
import type { VerifyCallback } from 'passport-oauth2'
|
||||
|
||||
export default async function oauthVerify(provider, profile, query, cb) {
|
||||
export type SocialLogin = {
|
||||
provider: string
|
||||
id: string
|
||||
displayName: string
|
||||
}
|
||||
|
||||
export default async function oauthVerify(
|
||||
provider: string,
|
||||
profile: Profile,
|
||||
query: Record<string, any>,
|
||||
cb: VerifyCallback
|
||||
) {
|
||||
process.nextTick(async () => {
|
||||
try {
|
||||
const email = profile.emails[0]?.value
|
||||
const email = profile.emails ? profile.emails[0]?.value : undefined
|
||||
if (!email) {
|
||||
return cb(new Error('No email found'))
|
||||
}
|
||||
@@ -26,7 +39,9 @@ export default async function oauthVerify(provider, profile, query, cb) {
|
||||
|
||||
return cb(null, user)
|
||||
} catch (err) {
|
||||
return cb(err)
|
||||
return cb(
|
||||
err instanceof Error ? err : new Error('An unknown error occurred')
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -5,17 +5,18 @@ import { get } from './utils/env.js'
|
||||
// Import dotenv and load ../.env
|
||||
dotenv.config({ path: '../.env' })
|
||||
|
||||
function getTrustProxies(key) {
|
||||
if (!process.env[key]) {
|
||||
function getTrustProxies(key: string): string[] {
|
||||
const value = process.env[key]
|
||||
if (!value) {
|
||||
return []
|
||||
}
|
||||
return process.env[key]
|
||||
return value
|
||||
.split(',')
|
||||
.map((p) => validator.trim(p))
|
||||
.filter((p) => validator.isIPRange(p) || validator.isIP(p))
|
||||
}
|
||||
|
||||
function getUrl(key) {
|
||||
function getUrl(key: string): string {
|
||||
const url = get(key, '')
|
||||
if (validator.isURL(url)) {
|
||||
return validator.trim(url)
|
||||
@@ -50,8 +51,8 @@ function createConfig() {
|
||||
clientSecret: get('GITHUB_CLIENT_SECRET', ''),
|
||||
},
|
||||
trustedProxies: getTrustProxies('TRUSTED_PROXIES'),
|
||||
surveyUrl: getUrl('SURVEY_URL', ''),
|
||||
bugReportUrl: getUrl('BUG_REPORT_URL', ''),
|
||||
surveyUrl: getUrl('SURVEY_URL'),
|
||||
bugReportUrl: getUrl('BUG_REPORT_URL'),
|
||||
|
||||
docker: {
|
||||
network: get('DOCKER_NETWORK', 'host'),
|
||||
@@ -74,7 +75,7 @@ function createConfig() {
|
||||
|
||||
const config = createConfig()
|
||||
|
||||
export function getQuestImage(id) {
|
||||
export function getQuestImage(id: string): string {
|
||||
return `${config.docker.imagePrefix}${id}`
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { User, UserProfile } from '@linux-odyssey/models'
|
||||
import { SocialLogin } from '../auth/oauthVerify.js'
|
||||
import { hashPassword } from '../utils/auth.js'
|
||||
|
||||
export async function createUser(username, email, { password, socialLogin }) {
|
||||
export async function createUser(
|
||||
username: string,
|
||||
email: string,
|
||||
{ password, socialLogin }: { password?: string; socialLogin?: SocialLogin }
|
||||
) {
|
||||
const user = new User({
|
||||
username,
|
||||
email,
|
||||
@@ -2,11 +2,11 @@ import jwt from 'jsonwebtoken'
|
||||
import bcrypt from 'bcrypt'
|
||||
import config from '../config.js'
|
||||
|
||||
export function hashPassword(password) {
|
||||
export function hashPassword(password: string): Promise<string> {
|
||||
return bcrypt.hash(password, 10)
|
||||
}
|
||||
|
||||
export function genJWT(payload) {
|
||||
export function genJWT(payload: any): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
jwt.sign(
|
||||
payload,
|
||||
@@ -15,6 +15,8 @@ export function genJWT(payload) {
|
||||
(err, token) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else if (token === undefined) {
|
||||
reject(new Error('Token is undefined'))
|
||||
} else {
|
||||
resolve(token)
|
||||
}
|
||||
@@ -23,7 +25,7 @@ export function genJWT(payload) {
|
||||
})
|
||||
}
|
||||
|
||||
export function verifyJWT(token) {
|
||||
export function verifyJWT(token: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
jwt.verify(token, config.secret, (err, decoded) => {
|
||||
if (err) {
|
||||
@@ -1,13 +0,0 @@
|
||||
import crypto from 'crypto'
|
||||
|
||||
export function get(key, defaultValue) {
|
||||
const value = process.env[key]
|
||||
if (value != null) {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
export function genSecret() {
|
||||
return crypto.randomUUID()
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import crypto from 'crypto'
|
||||
|
||||
export function get<T>(key: string, defaultValue: T): T {
|
||||
const value = process.env[key]
|
||||
return value !== undefined ? (value as unknown as T) : defaultValue
|
||||
}
|
||||
|
||||
export function genSecret() {
|
||||
return crypto.randomUUID()
|
||||
}
|
||||
File renamed without changes.
@@ -8,7 +8,10 @@ import logger from './logger.js'
|
||||
const questDirectory = path.join(process.cwd(), '..', 'quests')
|
||||
|
||||
class QuestValidationError extends Error {
|
||||
constructor(message, questId, error) {
|
||||
questId: string
|
||||
error: any
|
||||
|
||||
constructor(message: string, questId: string, error: any) {
|
||||
super(message)
|
||||
this.name = 'QuestValidationError'
|
||||
this.questId = questId
|
||||
@@ -16,7 +19,10 @@ class QuestValidationError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
async function mapQuests(callback) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
type QuestCallback = (id: string, questPath: string) => Promise<any>
|
||||
|
||||
async function mapQuests(callback: QuestCallback) {
|
||||
const questNames = await fs.readdir(questDirectory, {
|
||||
withFileTypes: true,
|
||||
})
|
||||
@@ -44,7 +50,7 @@ export async function loadAndUpdateQuests() {
|
||||
return mapQuests(async (id, questPath) => {
|
||||
const files = await fs.readdir(questPath)
|
||||
if (!files.includes('game.yml')) {
|
||||
throw new QuestValidationError(`Missing game.yml`, id)
|
||||
throw new QuestValidationError(`Missing game.yml`, id, null)
|
||||
}
|
||||
|
||||
try {
|
||||
File renamed without changes.
@@ -1351,6 +1351,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/bcrypt@npm:^5.0.2":
|
||||
version: 5.0.2
|
||||
resolution: "@types/bcrypt@npm:5.0.2"
|
||||
dependencies:
|
||||
"@types/node": "npm:*"
|
||||
checksum: 10c0/dd7f05e183b9b1fc08ec499069febf197ab8e9c720766b5bbb5628395082e248f9a444c60882fe7788361fcadc302e21e055ab9c26a300f100e08791c353e6aa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/body-parser@npm:*":
|
||||
version: 1.19.5
|
||||
resolution: "@types/body-parser@npm:1.19.5"
|
||||
@@ -1484,6 +1493,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/jsonwebtoken@npm:^9.0.5":
|
||||
version: 9.0.5
|
||||
resolution: "@types/jsonwebtoken@npm:9.0.5"
|
||||
dependencies:
|
||||
"@types/node": "npm:*"
|
||||
checksum: 10c0/c582b8420586f3b9550f7e34992cb32be300bc953636f3b087ed9c180ce7ea5c2e4b35090be2d57f0d3168cc3ca1074932907caa2afe09f4e9c84cf5c0daefa8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/mime@npm:*":
|
||||
version: 3.0.4
|
||||
resolution: "@types/mime@npm:3.0.4"
|
||||
@@ -1507,6 +1525,35 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/oauth@npm:*":
|
||||
version: 0.9.4
|
||||
resolution: "@types/oauth@npm:0.9.4"
|
||||
dependencies:
|
||||
"@types/node": "npm:*"
|
||||
checksum: 10c0/fcf8f5db7756a3e4d406ce3520abf78fecaf5e14963ad75fe0057425bb8b754e98d09dcb2b73a70e8fbe1e345b7d972d8090cf8cf08247e80d6eaac3acbe3fc7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/passport-oauth2@npm:^1.4.15":
|
||||
version: 1.4.15
|
||||
resolution: "@types/passport-oauth2@npm:1.4.15"
|
||||
dependencies:
|
||||
"@types/express": "npm:*"
|
||||
"@types/oauth": "npm:*"
|
||||
"@types/passport": "npm:*"
|
||||
checksum: 10c0/3f2b1c5c96ce0a1af9d55c07b18d68e443adccd9c5d429c0b08c6e35f0ca259bf77c29cecf2b94c1a035ce7c1c84087a2528e5ecc5ecfa0fba543e158bab7427
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/passport@npm:*, @types/passport@npm:^1.0.16":
|
||||
version: 1.0.16
|
||||
resolution: "@types/passport@npm:1.0.16"
|
||||
dependencies:
|
||||
"@types/express": "npm:*"
|
||||
checksum: 10c0/7120c1186c8c67e3818683b5b6a4439d102f67da93cc1c7d8f32484f7bf10e8438dd5de0bf571910b23d06caa43dd1ad501933b48618bfaf54e63219500993fe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/qs@npm:*":
|
||||
version: 6.9.11
|
||||
resolution: "@types/qs@npm:6.9.11"
|
||||
@@ -1577,6 +1624,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/validator@npm:^13.11.9":
|
||||
version: 13.11.9
|
||||
resolution: "@types/validator@npm:13.11.9"
|
||||
checksum: 10c0/856ebfcfe25d6c91a90235e0eb27302a737832530898195bbfb265da52ae7fe6d68f684942574f8818d3c262cae7a1de99f145dac73fc57217933af1bfc199cb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/webidl-conversions@npm:*":
|
||||
version: 7.0.3
|
||||
resolution: "@types/webidl-conversions@npm:7.0.3"
|
||||
@@ -8433,8 +8487,13 @@ __metadata:
|
||||
"@linux-odyssey/file-graph": "npm:*"
|
||||
"@linux-odyssey/models": "npm:*"
|
||||
"@linux-odyssey/utils": "npm:*"
|
||||
"@types/bcrypt": "npm:^5.0.2"
|
||||
"@types/express": "npm:^4.17.21"
|
||||
"@types/express-session": "npm:^1.17.10"
|
||||
"@types/jsonwebtoken": "npm:^9.0.5"
|
||||
"@types/passport": "npm:^1.0.16"
|
||||
"@types/passport-oauth2": "npm:^1.4.15"
|
||||
"@types/validator": "npm:^13.11.9"
|
||||
bcrypt: "npm:^5.1.1"
|
||||
commander: "npm:^11.0.0"
|
||||
concurrently: "npm:^8.2.2"
|
||||
|
||||
Reference in new issue
Block a user