Spaces:
Paused
Paused
Deploy Bot commited on
Commit ·
9c944bc
1
Parent(s): e1d320a
Add Phone Login and Bot Contact Handler
Browse files- src/api/routes.js +69 -0
- src/main.js +39 -1
src/api/routes.js
CHANGED
|
@@ -460,5 +460,74 @@ router.post('/auth/token', async (req, res) => {
|
|
| 460 |
}
|
| 461 |
});
|
| 462 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 463 |
module.exports = router;
|
| 464 |
|
|
|
|
| 460 |
}
|
| 461 |
});
|
| 462 |
|
| 463 |
+
// --- PHONE LOGIN ENDPOINTS ---
|
| 464 |
+
const OTP_STORE = new Map(); // Store OTPs: "998901234567" -> "1234"
|
| 465 |
+
|
| 466 |
+
router.post('/auth/send-code', async (req, res) => {
|
| 467 |
+
try {
|
| 468 |
+
const { phone } = req.body;
|
| 469 |
+
if (!phone) return res.status(400).json({ success: false, message: "Phone required" });
|
| 470 |
+
|
| 471 |
+
// Clean phone
|
| 472 |
+
const cleanPhone = phone.replace('+', '');
|
| 473 |
+
|
| 474 |
+
// Find user by phone
|
| 475 |
+
const user = await User.findOne({ phone: cleanPhone });
|
| 476 |
+
|
| 477 |
+
if (!user) {
|
| 478 |
+
return res.json({
|
| 479 |
+
success: false,
|
| 480 |
+
status: 'not_found',
|
| 481 |
+
message: "Ushbu raqam botda ro'yxatdan o'tmagan. Iltimos, botga kiring va raqamingizni yuboring."
|
| 482 |
+
});
|
| 483 |
+
}
|
| 484 |
+
|
| 485 |
+
// Generate Code
|
| 486 |
+
const code = Math.floor(1000 + Math.random() * 9000).toString();
|
| 487 |
+
OTP_STORE.set(cleanPhone, code);
|
| 488 |
+
|
| 489 |
+
// Send via Bot
|
| 490 |
+
try {
|
| 491 |
+
await req.bot.telegram.sendMessage(user.id, `🔐 <b>Tasdiqlash kodi:</b> <code>${code}</code>\n\nIlovaga kiriting.`, { parse_mode: 'HTML' });
|
| 492 |
+
res.json({ success: true, status: 'sent', message: "Kod yuborildi" });
|
| 493 |
+
} catch (botError) {
|
| 494 |
+
console.error("Bot Send Error:", botError);
|
| 495 |
+
res.json({ success: false, message: "Botga yuborib bo'lmadi. Botni bloklamaganmisiz?" });
|
| 496 |
+
}
|
| 497 |
+
|
| 498 |
+
} catch (e) {
|
| 499 |
+
console.error("Send Code Error:", e);
|
| 500 |
+
res.status(500).json({ success: false, message: "Server Error" });
|
| 501 |
+
}
|
| 502 |
+
});
|
| 503 |
+
|
| 504 |
+
router.post('/auth/verify-code', async (req, res) => {
|
| 505 |
+
try {
|
| 506 |
+
const { phone, code } = req.body;
|
| 507 |
+
const cleanPhone = phone.replace('+', '');
|
| 508 |
+
|
| 509 |
+
if (OTP_STORE.get(cleanPhone) === code) {
|
| 510 |
+
OTP_STORE.delete(cleanPhone); // Consume code
|
| 511 |
+
|
| 512 |
+
const user = await User.findOne({ phone: cleanPhone });
|
| 513 |
+
if (!user) return res.status(404).json({ success: false, message: "User not found" });
|
| 514 |
+
|
| 515 |
+
res.json({
|
| 516 |
+
success: true,
|
| 517 |
+
status: 'approved',
|
| 518 |
+
user: {
|
| 519 |
+
id: user.id.toString(),
|
| 520 |
+
name: user.first_name,
|
| 521 |
+
username: user.username
|
| 522 |
+
}
|
| 523 |
+
});
|
| 524 |
+
} else {
|
| 525 |
+
res.json({ success: false, message: "Kod noto'g'ri" });
|
| 526 |
+
}
|
| 527 |
+
} catch (e) {
|
| 528 |
+
res.status(500).json({ success: false, message: "Server Error" });
|
| 529 |
+
}
|
| 530 |
+
});
|
| 531 |
+
|
| 532 |
module.exports = router;
|
| 533 |
|
src/main.js
CHANGED
|
@@ -18,6 +18,12 @@ const apiRoutes = require('./api/routes');
|
|
| 18 |
const app = express();
|
| 19 |
app.use(cors());
|
| 20 |
app.use(bodyParser.json());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
app.use('/api', apiRoutes);
|
| 22 |
app.use('/public', express.static(path.join(__dirname, '../public'))); // Serve Static Files (APK, etc.)
|
| 23 |
|
|
@@ -97,7 +103,39 @@ bot.command('admin', (ctx) => {
|
|
| 97 |
|
| 98 |
// Admin Callbacks
|
| 99 |
bot.action('admin_dashboard', (ctx) => adminController.showDashboard(ctx));
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
bot.action('admin_api_generate', (ctx) => adminController.generateApiKey(ctx)); // NEW
|
| 102 |
|
| 103 |
bot.action('admin_users', (ctx) => adminController.showUsers(ctx));
|
|
|
|
| 18 |
const app = express();
|
| 19 |
app.use(cors());
|
| 20 |
app.use(bodyParser.json());
|
| 21 |
+
// Inject Bot into Request
|
| 22 |
+
const bot = require('../main');
|
| 23 |
+
app.use((req, res, next) => {
|
| 24 |
+
req.bot = bot;
|
| 25 |
+
next();
|
| 26 |
+
});
|
| 27 |
app.use('/api', apiRoutes);
|
| 28 |
app.use('/public', express.static(path.join(__dirname, '../public'))); // Serve Static Files (APK, etc.)
|
| 29 |
|
|
|
|
| 103 |
|
| 104 |
// Admin Callbacks
|
| 105 |
bot.action('admin_dashboard', (ctx) => adminController.showDashboard(ctx));
|
| 106 |
+
// Admin Callbacks
|
| 107 |
+
bot.action('admin_dashboard', (ctx) => adminController.showDashboard(ctx));
|
| 108 |
+
bot.action('admin_api', (ctx) => adminController.showApiMenu(ctx));
|
| 109 |
+
|
| 110 |
+
// --- CONTACT HANDLER (For Phone Login) ---
|
| 111 |
+
bot.on('contact', async (ctx) => {
|
| 112 |
+
try {
|
| 113 |
+
const contact = ctx.message.contact;
|
| 114 |
+
// Check if contact belongs to the user
|
| 115 |
+
if (contact.user_id !== ctx.from.id) {
|
| 116 |
+
return ctx.reply("🔒 Iltimos, o'zingizning raqamingizni yuboring (tugmani bosing).");
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
let user = await User.findOne({ id: ctx.from.id });
|
| 120 |
+
if (!user) {
|
| 121 |
+
user = new User({
|
| 122 |
+
id: ctx.from.id,
|
| 123 |
+
first_name: ctx.from.first_name,
|
| 124 |
+
username: ctx.from.username,
|
| 125 |
+
phone: contact.phone_number.replace('+', '')
|
| 126 |
+
});
|
| 127 |
+
await user.save();
|
| 128 |
+
} else {
|
| 129 |
+
user.phone = contact.phone_number.replace('+', '');
|
| 130 |
+
await user.save();
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
ctx.reply(`✅ <b>Raqam tasdiqlandi!</b>\n\nEndi ilovaga kirib, <b>${user.phone}</b> raqamini kiritsangiz, men sizga kod yuboraman.`, { parse_mode: 'HTML' });
|
| 134 |
+
} catch (e) {
|
| 135 |
+
console.error("Contact Error:", e);
|
| 136 |
+
ctx.reply("Xatolik yuz berdi.");
|
| 137 |
+
}
|
| 138 |
+
});
|
| 139 |
bot.action('admin_api_generate', (ctx) => adminController.generateApiKey(ctx)); // NEW
|
| 140 |
|
| 141 |
bot.action('admin_users', (ctx) => adminController.showUsers(ctx));
|