diff --git a/backend/.env.example b/backend/.env.example index dfaa308..3669675 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -18,3 +18,4 @@ MAIL_USER= MAIL_PASS= MAIL_FROM=noreply@linkedsign.local FRONTEND_URL=http://localhost:5173 +ANDROID_APK_PATH= diff --git a/backend/src/config/env.js b/backend/src/config/env.js index d8f1bd8..1aa162b 100644 --- a/backend/src/config/env.js +++ b/backend/src/config/env.js @@ -40,6 +40,8 @@ const env = { }, frontendUrl: process.env.FRONTEND_URL || 'http://localhost:5173', + androidApkPath: + process.env.ANDROID_APK_PATH || path.resolve(process.cwd(), '..', 'android', 'apk', 'LinkedSign-debug.apk'), }; module.exports = env; diff --git a/backend/src/modules/downloads/downloads.controller.js b/backend/src/modules/downloads/downloads.controller.js new file mode 100644 index 0000000..7924af6 --- /dev/null +++ b/backend/src/modules/downloads/downloads.controller.js @@ -0,0 +1,14 @@ +const downloadsService = require('./downloads.service'); + +const downloadAndroidApk = async (req, res, next) => { + try { + const { filePath, fileName } = await downloadsService.getAndroidApk(); + return res.download(filePath, fileName); + } catch (error) { + return next(error); + } +}; + +module.exports = { + downloadAndroidApk, +}; diff --git a/backend/src/modules/downloads/downloads.routes.js b/backend/src/modules/downloads/downloads.routes.js new file mode 100644 index 0000000..8acc5a9 --- /dev/null +++ b/backend/src/modules/downloads/downloads.routes.js @@ -0,0 +1,8 @@ +const express = require('express'); +const downloadsController = require('./downloads.controller'); + +const router = express.Router(); + +router.get('/android-apk', downloadsController.downloadAndroidApk); + +module.exports = router; diff --git a/backend/src/modules/downloads/downloads.service.js b/backend/src/modules/downloads/downloads.service.js new file mode 100644 index 0000000..9744950 --- /dev/null +++ b/backend/src/modules/downloads/downloads.service.js @@ -0,0 +1,24 @@ +const fs = require('fs/promises'); +const path = require('path'); +const env = require('../../config/env'); + +const getAndroidApk = async () => { + const filePath = env.androidApkPath; + + try { + await fs.access(filePath); + } catch { + const error = new Error('Android APK not found.'); + error.statusCode = 404; + throw error; + } + + return { + filePath, + fileName: path.basename(filePath), + }; +}; + +module.exports = { + getAndroidApk, +}; diff --git a/backend/src/routes/index.js b/backend/src/routes/index.js index 1fe1599..db9d8eb 100644 --- a/backend/src/routes/index.js +++ b/backend/src/routes/index.js @@ -1,6 +1,7 @@ const express = require('express'); const authRoutes = require('../modules/auth/auth.routes'); const certificatesRoutes = require('../modules/certificates/certificates.routes'); +const downloadsRoutes = require('../modules/downloads/downloads.routes'); const documentsRoutes = require('../modules/documents/documents.routes'); const signaturesRoutes = require('../modules/signatures/signatures.routes'); const usersRoutes = require('../modules/users/users.routes'); @@ -10,6 +11,7 @@ const router = express.Router(); router.use('/auth', authRoutes); router.use('/certificates', certificatesRoutes); +router.use('/downloads', downloadsRoutes); router.use('/documents', documentsRoutes); router.use('/signatures', signaturesRoutes); router.use('/users', usersRoutes); diff --git a/frontend/src/index.css b/frontend/src/index.css index dffce62..5fdcda6 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -391,6 +391,9 @@ select { .auth-link { text-align: center; margin-top: 20px; font-size: 13px; color: var(--gray-500); } .auth-link a { color: var(--primary); font-weight: 600; text-decoration: none; } .auth-link a:hover { text-decoration: underline; } +.auth-download-btn { + justify-content: center; +} /* ─── Form fields ────────────────────────────────────────────── */ .field { display: flex; flex-direction: column; gap: 5px; } diff --git a/frontend/src/pages/auth/LoginPage.jsx b/frontend/src/pages/auth/LoginPage.jsx index b11a9de..e0b1a8e 100644 --- a/frontend/src/pages/auth/LoginPage.jsx +++ b/frontend/src/pages/auth/LoginPage.jsx @@ -9,6 +9,8 @@ export default function LoginPage() { const navigate = useNavigate(); const [form, setForm] = useState({ email: '', password: '' }); const [loading, setLoading] = useState(false); + const apiBaseUrl = (import.meta.env.VITE_API_URL || 'http://localhost:4000').replace(/\/$/, ''); + const androidApkUrl = `${apiBaseUrl}/downloads/android-apk`; const handleChange = (e) => setForm((f) => ({ ...f, [e.target.name]: e.target.value })); @@ -54,6 +56,9 @@ export default function LoginPage() { + + Descargar app Android +

¿No tienes cuenta? Registrarse