2024-04-21 14:42:52 +02:00

119 lines
3.4 KiB
TypeScript

import '@/infra/env'
import { createServer, IncomingMessage, ServerResponse } from 'http'
import passport from 'passport'
import { BasicStrategy } from 'passport-http'
import { TokenAPI, Token } from '@/client/idp'
import { PORT } from '@/config'
import handleCopy from '@/handler/handle-copy'
import handleDelete from '@/handler/handle-delete'
import handleGet from '@/handler/handle-get'
import handleHead from '@/handler/handle-head'
import handleMkcol from '@/handler/handle-mkcol'
import handleMove from '@/handler/handle-move'
import handleOptions from '@/handler/handle-options'
import handlePropfind from '@/handler/handle-propfind'
import handleProppatch from '@/handler/handle-proppatch'
import handlePut from '@/handler/handle-put'
import { newExpiry } from '@/helper/token'
const tokens = new Map<string, Token>()
const expiries = new Map<string, Date>()
const api = new TokenAPI()
/* Refresh tokens */
setInterval(async () => {
for (const [username, token] of tokens) {
const expiry = expiries.get(username)
const earlyExpiry = new Date(expiry)
earlyExpiry.setMinutes(earlyExpiry.getMinutes() - 1)
if (new Date() >= earlyExpiry) {
const newToken = await api.exchange({
grant_type: 'refresh_token',
refresh_token: token.refresh_token,
})
tokens.set(username, newToken)
expiries.set(username, newExpiry(newToken))
}
}
}, 5000)
passport.use(
new BasicStrategy(async (username, password, done) => {
try {
let token = tokens.get(username)
if (!token) {
token = await new TokenAPI().exchange({
username,
password,
grant_type: 'password',
})
tokens.set(username, token)
expiries.set(username, newExpiry(token))
}
return done(null, token)
} catch (err) {
return done(err, false)
}
})
)
const server = createServer((req: IncomingMessage, res: ServerResponse) => {
if (req.url === '/v1/health' && req.method === 'GET') {
res.statusCode = 200
res.end('OK')
return
}
passport.authenticate(
'basic',
{ session: false },
async (err: Error, token: Token) => {
if (err || !token) {
res.statusCode = 401
res.setHeader('WWW-Authenticate', 'Basic realm="WebDAV Server"')
res.end()
} else {
const method = req.method
switch (method) {
case 'OPTIONS':
await handleOptions(req, res)
break
case 'GET':
await handleGet(req, res, token)
break
case 'HEAD':
await handleHead(req, res, token)
break
case 'PUT':
await handlePut(req, res, token)
break
case 'DELETE':
await handleDelete(req, res, token)
break
case 'MKCOL':
await handleMkcol(req, res, token)
break
case 'COPY':
await handleCopy(req, res, token)
break
case 'MOVE':
await handleMove(req, res, token)
break
case 'PROPFIND':
await handlePropfind(req, res, token)
break
case 'PROPPATCH':
await handleProppatch(req, res)
break
default:
res.statusCode = 501
res.end()
}
}
}
)(req, res)
})
server.listen(PORT, () => {
console.log(`Listening on port ${PORT}`)
})