diff options
Diffstat (limited to 'bskylink/src/routes/redirect.ts')
-rw-r--r-- | bskylink/src/routes/redirect.ts | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/bskylink/src/routes/redirect.ts b/bskylink/src/routes/redirect.ts index 7d68e4245..681dc0bb9 100644 --- a/bskylink/src/routes/redirect.ts +++ b/bskylink/src/routes/redirect.ts @@ -1,10 +1,13 @@ import assert from 'node:assert' import {DAY, SECOND} from '@atproto/common' -import escapeHTML from 'escape-html' import {type Express} from 'express' import {type AppContext} from '../context.js' +import {linkRedirectContents} from '../html/linkRedirectContents.js' +import {linkWarningContents} from '../html/linkWarningContents.js' +import {linkWarningLayout} from '../html/linkWarningLayout.js' +import {redirectLogger} from '../logger.js' import {handler} from './util.js' const INTERNAL_IP_REGEX = new RegExp( @@ -39,14 +42,54 @@ export default function (ctx: AppContext, app: Express) { return res.status(302).end() } + // Default to a max age header res.setHeader('Cache-Control', `max-age=${(7 * DAY) / SECOND}`) - res.type('html') res.status(200) + res.type('html') - const escaped = escapeHTML(url.href) - return res.send( - `<html><head><meta http-equiv="refresh" content="0; URL='${escaped}'" /><style>:root { color-scheme: light dark; }</style></head></html>`, - ) + let html: string | undefined + + if (ctx.cfg.service.safelinkEnabled) { + const rule = await ctx.safelinkClient.tryFindRule(link) + if (rule !== 'ok') { + switch (rule.action) { + case 'whitelist': + redirectLogger.info({rule}, 'Whitelist rule matched') + break + case 'block': + html = linkWarningLayout( + 'Blocked Link Warning', + linkWarningContents(req, { + type: 'block', + link: url.href, + }), + ) + res.setHeader('Cache-Control', 'no-store') + redirectLogger.info({rule}, 'Block rule matched') + break + case 'warn': + html = linkWarningLayout( + 'Malicious Link Warning', + linkWarningContents(req, { + type: 'warn', + link: url.href, + }), + ) + res.setHeader('Cache-Control', 'no-store') + redirectLogger.info({rule}, 'Warn rule matched') + break + default: + redirectLogger.warn({rule}, 'Unknown rule matched') + } + } + } + + // If there is no html defined yet, we will create a redirect html + if (!html) { + html = linkRedirectContents(url.href) + } + + return res.end(html) }), ) } |