|
|
@ -0,0 +1,126 @@ |
|
|
|
import { SQLQuery, sql } from '@databases/pg' |
|
|
|
import { FastifyPluginAsync } from 'fastify' |
|
|
|
import S from 'jsonschema-definer' |
|
|
|
|
|
|
|
import { db } from '../shared' |
|
|
|
import { sUserSettings } from './types' |
|
|
|
|
|
|
|
export const userRouter: FastifyPluginAsync = async (f) => { |
|
|
|
{ |
|
|
|
const sQuery = S.shape({ |
|
|
|
select: S.string(), |
|
|
|
}) |
|
|
|
|
|
|
|
const sResponse = sUserSettings.partial() |
|
|
|
|
|
|
|
f.get<{ |
|
|
|
Querystring: typeof sQuery.type |
|
|
|
}>( |
|
|
|
'/', |
|
|
|
{ |
|
|
|
schema: { |
|
|
|
operationId: 'userGetSettings', |
|
|
|
querystring: sQuery.valueOf(), |
|
|
|
response: { |
|
|
|
200: sResponse.valueOf(), |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
async (req): Promise<typeof sResponse.type> => { |
|
|
|
const select = req.query.select.split( |
|
|
|
',' |
|
|
|
) as (keyof typeof sUserSettings.type)[] |
|
|
|
|
|
|
|
const userId: string = req.session['userId'] |
|
|
|
if (!userId) { |
|
|
|
throw { statusCode: 403 } |
|
|
|
} |
|
|
|
|
|
|
|
const selMap: Record<keyof typeof sUserSettings.type, SQLQuery> = { |
|
|
|
identifier: sql`"identifier"`, |
|
|
|
level: sql`"level"`, |
|
|
|
levelMin: sql`"levelMin"`, |
|
|
|
level_browser: sql`"level_browser"`, |
|
|
|
} |
|
|
|
|
|
|
|
const sel = select.map((s) => selMap[s]).filter((s) => s) |
|
|
|
|
|
|
|
if (!sel.length) { |
|
|
|
throw { statusCode: 400, message: 'not enough select' } |
|
|
|
} |
|
|
|
|
|
|
|
const [r] = await db.query( |
|
|
|
sql`
|
|
|
|
SELECT ${sql.join(sel, ',')} FROM "user" WHERE "id" = ${userId} |
|
|
|
`
|
|
|
|
) |
|
|
|
if (!r) { |
|
|
|
throw { statusCode: 403 } |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
identifier: r.identifier || undefined, |
|
|
|
level: r.level || undefined, |
|
|
|
levelMin: r.levelMin || undefined, |
|
|
|
level_browser: r.levelBrowser || undefined, |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
const sBody = sUserSettings.partial() |
|
|
|
|
|
|
|
const sResult = S.shape({ |
|
|
|
result: S.string(), |
|
|
|
}) |
|
|
|
|
|
|
|
f.patch<{ |
|
|
|
Body: Partial<typeof sUserSettings.type> |
|
|
|
}>( |
|
|
|
'/', |
|
|
|
{ |
|
|
|
schema: { |
|
|
|
operationId: 'userUpdateSettings', |
|
|
|
body: sBody.valueOf(), |
|
|
|
response: { |
|
|
|
201: sResult.valueOf(), |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
async (req, reply): Promise<typeof sResult.type> => { |
|
|
|
const userId: string = req.session['userId'] |
|
|
|
if (!userId) { |
|
|
|
throw { statusCode: 403 } |
|
|
|
} |
|
|
|
|
|
|
|
if (!Object.keys(req.body).length) { |
|
|
|
throw { statusCode: 400, message: 'not enough update' } |
|
|
|
} |
|
|
|
|
|
|
|
const uMap: Partial<Record<keyof typeof sUserSettings.type, SQLQuery>> = |
|
|
|
{ |
|
|
|
level: sql`"level" = ${req.body.level}`, |
|
|
|
levelMin: sql`"levelMin" = ${req.body.levelMin}`, |
|
|
|
level_browser: sql`"level_browser" = ${req.body.level_browser}`, |
|
|
|
} |
|
|
|
|
|
|
|
await db.tx(async (db) => { |
|
|
|
await db.query(sql`
|
|
|
|
UPDATE "user" |
|
|
|
SET ${sql.join( |
|
|
|
Object.keys(req.body).map((k) => (uMap as any)[k]), |
|
|
|
',' |
|
|
|
)} |
|
|
|
WHERE "id" = ${userId} |
|
|
|
`)
|
|
|
|
}) |
|
|
|
|
|
|
|
reply.status(201) |
|
|
|
return { |
|
|
|
result: 'updated', |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
} |