From 96b5c6bf8d1efacb7022f9947524ec959aaf5da5 Mon Sep 17 00:00:00 2001 From: Chenyu Huang Date: Thu, 31 Jul 2025 16:10:32 -0700 Subject: [PATCH] setup i18n --- bskylink/locales/en.json | 8 +++++++ bskylink/locales/es.json | 8 +++++++ bskylink/locales/fr.json | 8 +++++++ bskylink/package.json | 2 ++ bskylink/src/html/linkWarningContents.ts | 30 +++++++++++++++++------- bskylink/src/i18n.ts | 15 ++++++++++++ bskylink/src/index.ts | 7 +++++- bskylink/src/routes/redirect.ts | 4 ++-- 8 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 bskylink/locales/en.json create mode 100644 bskylink/locales/es.json create mode 100644 bskylink/locales/fr.json create mode 100644 bskylink/src/i18n.ts diff --git a/bskylink/locales/en.json b/bskylink/locales/en.json new file mode 100644 index 0000000000..b204ad51cf --- /dev/null +++ b/bskylink/locales/en.json @@ -0,0 +1,8 @@ +{ + "Potentially Dangerous Link": "Potentially Dangerous Link", + "Blocked Link": "Blocked Link", + "This link may be malicious. You should proceed at your own risk.": "This link may be malicious. You should proceed at your own risk.", + "This link has been identified as malicious and has blocked for your safety.": "This link has been identified as malicious and has blocked for your safety.", + "Continue Anyway": "Continue Anyway", + "Return to Bluesky": "Return to Bluesky" +} diff --git a/bskylink/locales/es.json b/bskylink/locales/es.json new file mode 100644 index 0000000000..fdf3f19636 --- /dev/null +++ b/bskylink/locales/es.json @@ -0,0 +1,8 @@ +{ + "Potentially Dangerous Link": "Enlace Potencialmente Peligroso", + "Blocked Link": "Enlace Bloqueado", + "This link may be malicious. You should proceed at your own risk.": "Este enlace puede ser malicioso. Debes proceder bajo tu propio riesgo.", + "This link has been identified as malicious and has blocked for your safety.": "Este enlace ha sido identificado como malicioso y ha sido bloqueado por tu seguridad.", + "Continue Anyway": "Continuar de Todos Modos", + "Return to Bluesky": "Regresar a Bluesky" +} diff --git a/bskylink/locales/fr.json b/bskylink/locales/fr.json new file mode 100644 index 0000000000..1fdc7e6ad6 --- /dev/null +++ b/bskylink/locales/fr.json @@ -0,0 +1,8 @@ +{ + "Potentially Dangerous Link": "Lien Potentiellement Dangereux", + "Blocked Link": "Lien Bloqué", + "This link may be malicious. You should proceed at your own risk.": "Ce lien peut être malveillant. Vous devriez procéder à vos propres risques.", + "This link has been identified as malicious and has blocked for your safety.": "Ce lien a été identifié comme malveillant et a été bloqué pour votre sécurité.", + "Continue Anyway": "Continuer Quand Même", + "Return to Bluesky": "Retourner à Bluesky" +} diff --git a/bskylink/package.json b/bskylink/package.json index e254806657..a2487ef642 100644 --- a/bskylink/package.json +++ b/bskylink/package.json @@ -15,6 +15,7 @@ "escape-html": "^1.0.3", "express": "^4.19.2", "http-terminator": "^3.2.0", + "i18n": "^0.15.1", "kysely": "^0.27.3", "pg": "^8.12.0", "pino": "^9.2.0", @@ -23,6 +24,7 @@ }, "devDependencies": { "@types/cors": "^2.8.17", + "@types/i18n": "^0.13.12", "@types/pg": "^8.11.6", "typescript": "^5.4.5" } diff --git a/bskylink/src/html/linkWarningContents.ts b/bskylink/src/html/linkWarningContents.ts index d55f085870..e4585d88af 100644 --- a/bskylink/src/html/linkWarningContents.ts +++ b/bskylink/src/html/linkWarningContents.ts @@ -1,19 +1,29 @@ import escapeHTML from 'escape-html' +import {type Request} from 'express' import {type Hole, html} from 'uhtml' -export function linkWarningContents(opts: { - type: 'warn' | 'block' - link: string -}): Hole { +export function linkWarningContents( + req: Request, + opts: { + type: 'warn' | 'block' + link: string + }, +): Hole { return html`
⚠️

- ${opts.type === 'warn' ? 'Potentially Dangerous Link' : 'Blocked Link'} + ${opts.type === 'warn' + ? req.__('Potentially Dangerous Link') + : req.__('Blocked Link')}

${opts.type === 'warn' - ? 'This link may be malicious. You should proceed at your own risk.' - : 'This link has been identified as malicious and has blocked for your safety.'} + ? req.__( + 'This link may be malicious. You should proceed at your own risk.', + ) + : req.__( + 'This link has been identified as malicious and has blocked for your safety.', + )}

${escapeHTML(opts.link)}

@@ -21,10 +31,12 @@ export function linkWarningContents(opts: {
${opts.type === 'warn' ? html`Continue Anyway${req.__('Continue Anyway')}` : null} - Return to Bluesky + ${req.__('Return to Bluesky')}
` } diff --git a/bskylink/src/i18n.ts b/bskylink/src/i18n.ts new file mode 100644 index 0000000000..8ecac31179 --- /dev/null +++ b/bskylink/src/i18n.ts @@ -0,0 +1,15 @@ +import path from 'node:path' +import {fileURLToPath} from 'node:url' + +import i18n from 'i18n' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +i18n.configure({ + locales: ['en', 'es', 'fr'], + defaultLocale: 'en', + directory: path.join(__dirname, '../locales'), +}) + +export default i18n diff --git a/bskylink/src/index.ts b/bskylink/src/index.ts index f19f4149a7..c7d52681df 100644 --- a/bskylink/src/index.ts +++ b/bskylink/src/index.ts @@ -7,6 +7,7 @@ import {createHttpTerminator, type HttpTerminator} from 'http-terminator' import {type Config} from './config.js' import {AppContext} from './context.js' +import i18n from './i18n.js' import {default as routes, errorHandler} from './routes/index.js' export * from './config.js' @@ -17,11 +18,15 @@ export class LinkService { public server?: http.Server private terminator?: HttpTerminator - constructor(public app: express.Application, public ctx: AppContext) {} + constructor( + public app: express.Application, + public ctx: AppContext, + ) {} static async create(cfg: Config): Promise { let app = express() app.use(cors()) + app.use(i18n.init) const ctx = await AppContext.fromConfig(cfg) app = routes(ctx, app) diff --git a/bskylink/src/routes/redirect.ts b/bskylink/src/routes/redirect.ts index 0fa6392979..9a311da942 100644 --- a/bskylink/src/routes/redirect.ts +++ b/bskylink/src/routes/redirect.ts @@ -68,7 +68,7 @@ export default function (ctx: AppContext, app: Express) { case ToolsOzoneSafelinkDefs.BLOCK: hole = linkWarningLayout( 'Blocked Link Warning', - linkWarningContents({ + linkWarningContents(req, { type: 'block', link: url.href, }), @@ -79,7 +79,7 @@ export default function (ctx: AppContext, app: Express) { case ToolsOzoneSafelinkDefs.WARN: hole = linkWarningLayout( 'Malicious Link Warning', - linkWarningContents({ + linkWarningContents(req, { type: 'warn', link: url.href, }),