Compare commits

..

2 الالتزامات

المؤلف SHA1 الرسالة التاريخ
7ae3010b7f no reset password
فشلت بعض الفحوصات
Docker Build and Push (Development) / build-and-push-dev (push) Has been cancelled
Release Please / release-please (push) Has been cancelled
2025-11-25 23:19:11 +03:00
e94d92bf3b added umami 2025-11-17 17:21:43 +03:00
12 ملفات معدلة مع 108 إضافات و65 حذوفات

عرض الملف

@@ -1,23 +1,12 @@
.git/
.gitignore
.dockerignore
docker-compose*
Dockerfile
makefile
htmlcov/
coverage.xml
.coverage*
.vscode/
*.dat
.DS_Store
node_modules
/build
/package
.git
.gitignore
README.md
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.idea
.npm
.cache
dist
*.log
.DS_Store
coverage
.nyc_output

عرض الملف

@@ -3,7 +3,7 @@
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
"module": "CommonJS" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
"module": "node16" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
// "lib": [], /* Specify library files to be included in the compilation. */
"allowJs": true /* Allow javascript files to be compiled. */,
// "checkJs": true, /* Report errors in .js files. */
@@ -38,7 +38,7 @@
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
"moduleResolution": "node16" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */

47
debug-resend.ts Normal file
عرض الملف

@@ -0,0 +1,47 @@
// debug-resend.js
require('dotenv').config();
const { Resend } = require('resend');
console.log('🔍 Debugging Resend...');
// Check environment
console.log('RESEND_API_KEY exists:', !!process.env.RESEND_API_KEY);
console.log('RESEND_API_KEY starts with:', process.env.RESEND_API_KEY ? process.env.RESEND_API_KEY.substring(0, 3) : 'N/A');
console.log('FROM_EMAIL:', process.env.FROM_EMAIL);
if (!process.env.RESEND_API_KEY) {
console.log('❌ RESEND_API_KEY is missing!');
process.exit(1);
}
const resend = new Resend(process.env.RESEND_API_KEY);
async function test() {
try {
console.log('\n🚀 Testing Resend API...');
const { data, error } = await resend.emails.send({
from: process.env.FROM_EMAIL || 'myDrive <onboarding@resend.dev>',
to: 'hamodeh.mnzk@gmail.com',
subject: 'Resend Test',
text: 'This is a test email from Resend.',
});
if (error) {
console.log('❌ Resend API Error:');
console.log('Error name:', error.name);
console.log('Error message:', error.message);
console.log('Error status:', error.statusCode);
return;
}
console.log('✅ Email sent!');
console.log('Email ID:', data.id);
} catch (err) {
console.log('❌ Unexpected error:');
console.log(err.message);
}
}
test();

عرض الملف

@@ -2,14 +2,17 @@
<html>
<head>
<title>myDrive</title>
<title>FlowSync | Drive</title>
<link rel="icon" href="/images/icon.png" />
<link rel="shortcut icon" type="image/png" href="/images/icon.png" />
<link rel="shortcut icon" sizes="192x192" href="/images/icon.png" />
<link rel="apple-touch-icon" href="/images/icon.png" />
<link rel="shortcut icon" type="image/png" href="/public/images/favicon-32x32.png" />
<link rel="shortcut icon" sizes="192x192" href="/public/images/favicon-32x32.png" />
<link rel="apple-touch-icon" href="/public/images/favicon-32x32.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script defer src="https://cloud.umami.is/script.js" data-website-id="ce3be986-8a39-489c-8e77-c77c253acbd4"></script>
</head>
<body>

عرض الملف

@@ -27,7 +27,7 @@
"aws-sdk": "^2.657.0",
"axios": "^1.7.2",
"bcryptjs": "^3.0.2",
"body-parser": "^1.20.2",
"body-parser": "^2.2.1",
"bytes": "^3.1.0",
"classnames": "^2.5.1",
"cli-progress": "^3.6.0",
@@ -40,7 +40,7 @@
"cors": "^2.8.5",
"dayjs": "^1.11.13",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^5.1.0",
"express-validator": "^7.1.0",
"fluent-ffmpeg": "^2.1.3",
"helmet": "^3.21.2",
@@ -49,7 +49,7 @@
"lodash.debounce": "^4.0.8",
"mongodb": "^6.20.0",
"mongoose": "^8.4.1",
"nodemailer": "^6.9.14",
"nodemailer": "^7.0.10",
"normalize.css": "^8.0.1",
"password-prompt": "^1.1.2",
"progress-stream": "^2.0.0",
@@ -64,6 +64,7 @@
"react-toastify": "^10.0.5",
"redux": "^5.0.1",
"regenerator-runtime": "^0.13.3",
"resend": "^6.5.2",
"sharp": "^0.33.4",
"sweetalert2": "^11.15.10",
"temp": "^0.9.1",
@@ -88,6 +89,7 @@
"@types/connect-busboy": "0.0.2",
"@types/cookie-parser": "^1.4.2",
"@types/cors": "^2.8.17",
"@types/dotenv": "^6.1.1",
"@types/express": "^4.17.21",
"@types/fluent-ffmpeg": "^2.1.24",
"@types/helmet": "0.0.45",
@@ -128,7 +130,7 @@
"tailwindcss": "^3.4.4",
"typescript": "^5.4.5",
"typescript-eslint": "^7.14.1",
"vite": "^5.2.13",
"vite-plugin-pwa": "^0.21.1"
"vite": "^6.0.0",
"vite-plugin-pwa": "^1.1.0"
}
}

ثنائية
public/images/favicon-32x32.png Normal file

ملف ثنائي غير معروض.

بعد

العرض:  |  الارتفاع:  |  الحجم: 785 B

ثنائية
public/images/icon.png

ملف ثنائي غير معروض.

قبل

العرض:  |  الارتفاع:  |  الحجم: 6.3 KiB

عرض الملف

@@ -4,7 +4,7 @@ import axios from "../axiosInterceptor";
export const getUserToken = async () => {
const response = await axios.post("/user-service/get-token");
response.data;
return response.data; // FIXED: Added return
};
export const getUserAPI = async () => {
@@ -54,6 +54,12 @@ export const getAccessToken = async (uuid: string) => {
return response.data;
};
export const sendPasswordResetAPI = async (email: string) => {
const response = await axios.post("/api/user-service/send-password-reset", {
email,
});
return response.data;
};
// PATCH
export const changePasswordAPI = async (
@@ -79,13 +85,6 @@ export const verifyEmailAPI = async (emailToken: string) => {
return response.data;
};
export const sendPasswordResetAPI = async (email: string) => {
const response = await axios.patch("/user-service/send-password-reset", {
email,
});
return response.data;
};
export const resetPasswordAPI = async (
password: string,
passwordToken: string

عرض الملف

@@ -9,7 +9,7 @@ const LandingPage = () => {
<div className="landing-page">
{/* Header */}
<div className="header">
<div className="logo">🌊 FlowSync</div>
<div className="logo"> FlowSync</div>
<div className="header-buttons">
<button className="btn-secondary" onClick={() => navigate('/login')}>Sign In</button>
<button className="btn-primary" onClick={() => navigate('/register')}>Get Started</button>
@@ -516,8 +516,7 @@ const LandingPage = () => {
<div className="footer">
<div className="footer-content">
<div className="footer-brand">
<div className="logo">🌊 FlowSpace</div>
<p>Innovating the future of digital storage and collaboration</p>
<div className="logo"> FlowSync</div> <p>Innovating the future of digital storage and collaboration</p>
<p className="footer-tagline">Secure. Simple. Seamless.</p>
</div>
<div className="footer-links">

عرض الملف

@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from "react";
import { useEffect, useRef, useState, useCallback ,FormEvent } from "react";
import {
createAccountAPI,
getUserAPI,
@@ -16,6 +16,8 @@ import Swal from "sweetalert2";
import { AxiosError } from "axios";
import isEmail from "validator/es/lib/isEmail";
// ADD THE defaultView PROP HERE
const LoginPage = ({ defaultView = "login" }) => {
const [email, setEmail] = useState("");
@@ -30,7 +32,7 @@ const LoginPage = ({ defaultView = "login" }) => {
const navigate = useNavigate();
const lastSentPassowordReset = useRef(0);
const attemptLoginWithToken = async () => {
const attemptLoginWithToken = useCallback(async () => {
setAttemptingLogin(true);
try {
@@ -47,7 +49,7 @@ const LoginPage = ({ defaultView = "login" }) => {
window.localStorage.removeItem("hasPreviouslyLoggedIn");
}
}
};
}, [location.state?.from?.pathname, dispatch, navigate]);
const login = async () => {
try {
@@ -147,7 +149,7 @@ const LoginPage = ({ defaultView = "login" }) => {
}
})();
const onSubmit = (e: any) => {
const onSubmit = (e: FormEvent) => {
e.preventDefault();
if (mode === "login") {
login();
@@ -156,7 +158,7 @@ const LoginPage = ({ defaultView = "login" }) => {
} else if (mode === "reset") {
resetPassword();
}
};
};
const headerTitle = (() => {
switch (mode) {
@@ -290,10 +292,10 @@ const LoginPage = ({ defaultView = "login" }) => {
<button
type="button"
className="text-[#3182ce] text-[14px] font-medium no-underline mr-4 hover:text-[#2c5aa0] transition-colors duration-200"
onClick={() => setMode("reset")}
>
onClick={() => navigate("/forgot-password")} // This navigates to the actual page
>
Forgot?
</button>
</button>
</div>
)}
</div>

عرض الملف

@@ -13,6 +13,7 @@ import Homepage from "../components/Homepage/Homepage";
import SettingsPage from "../components/SettingsPage/SettingsPage";
import LandingPage from '../components/LandingPage/LandingPage';
import PrivateRoute from "./PrivateRoute";
import ForgotPasswordPage from "../components/ForgotPasswordPage/ForgotPasswordPage";
const AppRouter = () => {
return (
@@ -23,6 +24,7 @@ const AppRouter = () => {
<Route path="/welcome" element={<Navigate to="/" replace />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<LoginPage defaultView="create" />} />
<Route path="/forgot-password" element={<ForgotPasswordPage />} />
<Route path="/public-download/:id/:tempToken" element={<DownloadPage />} />
<Route path="/verify-email/:token" element={<VerifyEmailPage />} />
<Route path="/reset-password/:token" element={<ResetPasswordPage />} />

عرض الملف

@@ -20,6 +20,6 @@
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"include": ["src", "backend/utils/emailService.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}