├── LICENSE ├── README.md └── worker.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 wuzf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2fa 2 | 这是一个用Cloudflare Worker代码实现的Two Factor Authentication,worker页面会显示动态生成的 One-Time Password(OTP),并且能够在 OTP 过期后自动刷新以提供新的 OTP,可以简单代替Google Authenticator或者Microsoft Authenticator。 3 | 如果不想用演示站,也可以自己复制worker.js源码,通过Cloudflare Worker自行搭建。 4 | 5 | ### 演示网站 6 | https://2fa.free.hr/MBWJJVDIQ3PH3SA5 7 | 8 | ### 备用网站: 9 | 1. https://2fa.guts.eu.org/MBWJJVDIQ3PH3SA5 10 | 2. https://2fa.my2fa.workers.dev/MBWJJVDIQ3PH3SA5 11 | 3. https://tfa.mytfa.workers.dev/MBWJJVDIQ3PH3SA5 12 | -------------------------------------------------------------------------------- /worker.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | // src/index.js 3 | addEventListener("fetch", (event) => { 4 | event.respondWith(handleRequest(event.request)); 5 | }); 6 | async function handleRequest(request) { 7 | const url = new URL(request.url); 8 | const secret = url.pathname.substring(1); 9 | if (!secret) { 10 | return new Response("Missing secret parameter", { status: 400 }); 11 | } 12 | const loadTime = Math.floor(Date.now() / 1e3); 13 | const otp = await generateOTP(secret, loadTime); 14 | const htmlContent = ` 15 | 16 | 17 | OTP Page 18 |