Sistem Analizi ve Tasarımı dersi için Gider Takip Sistemi projesidir.
Projenin canlı demo sürümüne buradan erişebilirsiniz.
Bu projede aşağıdaki teknolojiler ve kütüphaneler kullanılmıştır:
- Node.js: Sunucu tarafında JavaScript çalıştırmak için kullanılan platform.
- Express.js: Web uygulamaları ve API geliştirmek için kullanılan minimal ve esnek bir Node.js framework'ü.
- Mongoose: MongoDB ile etkileşim kurmak için kullanılan bir ODM (Object Data Modeling) kütüphanesi.
- argon2: Şifreleme ve doğrulama işlemleri için kullanılan güçlü bir şifreleme algoritması.
- jsonwebtoken (JWT): Kullanıcı kimlik doğrulama ve yetkilendirme için kullanılan token tabanlı bir çözüm.
- express-rate-limit: Şifre sıfırlama gibi işlemler için istek sınırlandırma.
- express-mongo-sanitize: NoSQL Injection saldırılarına karşı koruma sağlamak için kullanılan middleware.
- nodemailer: E-posta gönderimi için kullanılan kütüphane.
- EJS (Embedded JavaScript): Dinamik HTML şablonları oluşturmak için kullanılan bir şablon motoru.
- Bootstrap 5: Kullanıcı arayüzü tasarımı için kullanılan CSS framework'ü.
- Chart.js: Giderlerin görselleştirilmesi için kullanılan grafik kütüphanesi.
- Font Awesome: İkonlar için kullanılan bir kütüphane.
- ExcelJS: Giderleri Excel formatında dışa aktarmak için kullanılan kütüphane.
- PDFKit: Giderleri PDF formatında dışa aktarmak için kullanılan kütüphane.
- csv-writer: Giderleri CSV formatında dışa aktarmak için kullanılan kütüphane.
- moment-timezone: Tarih ve saat işlemleri için kullanılan kütüphane.
- ms: Süreleri kolayca işlemek için kullanılan bir yardımcı kütüphane.
- Bu proje Node.js v18 ve üzeri sürümleri içindir.
- Proje de veritabanı olarak MongoDB kullanılmıştır ve bir MongoDB veritabanına sahip olmalısınız.
- E-posta servisi olarak Gmail kullanılmıştır ve bir Google hesabına sahip olmalısınız.
- Projeyi çalıştırmak için aşağıdaki adımları izleyiniz:
-
Depoyu Klonlayın
git clone https://github.com/Vu4ll/satcd sat
-
Gerekli Kütüphaneleri Yükleyin
npm install
-
Değişkenleri Ayarlayın
.envdosyası oluşturun ve gerekli değişkenleri ekleyin. Örnek.envdosyası:
MONGO_URI=your_mongodb_uri # Required
JWT_SECRET=your_jwt_secret # Required
APP_URL=your_app_url # Optional, default is http://localhost
PORT=your_port # Optional, default is 3000
COOKIE_MAX_AGE=your_max_age # Optional, in day format, default is 7d
COOKIE_SECRET=your_cookie_secret # Required
LOCALE=your_locale # Optional, default is tr
TIMEZONE=your_timezone # Optional, default is Europe/Istanbul
RESET_PASSWORD_EXPIRES=your_reset_password_expires # Optional, in hour format, default is 1h
MAIL_USER=your_gmail # Required
MAIL_PASS=your_app_pass_or_password # Required
DEFAULT_CHART_COLOR=your_chart_color # Optional, in hex color format without #, default is 5CC593
PASSWORD_RESET_RATE_LIMIT=your_rate_limit # Optional, in minute format, default is 15m
PASSWORD_RESET_MAX_ATTEMPT=your_max_attempt # Optional, default is 3-
Web Uygulamasını Başlatın
npm startkomutunu girerek veya Visual Studio Code üzerinden F5 tuşu ile uygulamayı başlatabilirsiniz.
-
Tarayıcınızdan Açın
- Tarayıcınızda http://localhost:3000 adresine gidin.
- ✅ | Session yönetiminden çerezlere geçilecek.
express-sessionkütüphanesindencookie-parserkütüphanesi kullanılarak çerez kullanımına geçildi.
- ✅ | Dashboard da gider tarihlerinde saat yazmıyor ve saatler veritabanına +0 saat diliminde kaydediliyor bu sorunun çözümü araştırılacak.
moment-timezonekütüphanesi kullanılarak kullanıcının saat dilimini çerezlere kaydederek o saat dilimine göre görüntülenmesi sağlandı.- Tarih 22 Mart 2025 21:27 şeklinde görüntülenmekte ama bunu kullanıcının dil bilgisi çerezlerde tutularak göre
moment.locale()kullanarak işlenmektedir. - Kullanıcı tarayıcı dili Felemenkçe olarak kullanıyorsa onun saat dilimi ve diline göre göstermektedir. Yani az önce ki tarih kullanıcı da 22 maart 2025 19:27 olarak gözükecektir.
- Gider miktarları çerezlerden alınan dil bilgisine göre
toLocaleString()metodu kullanılarak biçimlendirilmiş şekilde gösterilmektedir.
- ✅ | Şifre sıfırlama.
nodemailerkütüphanesi kuruldu.- Test etmek için
nodemaileriçerisinde dahil olan test e-postası gönderilmesi denendi.util/testmail.js - Şifre sıfırlama işlemi için formlar oluşturuldu 1 saat geçerli bir token ile şifre sıfırlama işlemi gerçekleştirilmektedir.
- Şifre sıfırlama talebinden 5 saniye sonra otomatik olarak
/loginhedefine yönlendirme yapılmaktadır. - Token doğrulaması ile güvenlik sağlandı.
- Gerçek e-posta gönderilmesi Google aracılıyla sağlandı.
- ✅ |
login.ejsveregister.ejsdüzenlenecek.- Bir hesabınız yok mu? ve Hesabınız var mı? yazıları eklendi.
- Şifrenizi mi unuttunuz? yazısı eklendi.
- Girişlere
placeholdereklendi. - Kayıt olma işlemi için şifrenin 2 kere girilmesi sağlandı.
- ✅ | Sabitler
.envdosyasına taşınacak.- Sabitler
.envdosyasına taşındı ve varsayılan değerler belirtildi.
- Sabitler
- ✅ |
chart.jsile grafik oluşturulacak.- Gider verilerini almak için API oluşturuldu.
- HTML içerisinde bu API verilerini grafikte kullanmak için fonksiyon oluşturuldu.
views/js/fetch-expenses.js - API için kullanıcı yetkilendirmesi ile güvenlik sağlandı.
- ✅ | Gider kategorileri HTML içerisinde yer almayacak onun yerine veritabanından çekilecek ve bu veriler işlenecek.
- Kategoriler için veritabanı modeli oluşturuldu.
- Geçiçi olarak elle kategorilerin eklenmesi için
/add-categorieshedefi eklendi. - Backend tarafta veriler işlenip frontend tarafa gönderilerek seçeneklerin görüntülenmesi sağlandı.
- ✅ | Kategori düzenleme paneli oluşturulacak.
- Panel için
/categorieshedefi oluşturuldu. - Panelde kategoriler listelenmekte ve her kategori için düzenleme ve silme butonları bulunmaktadır.
- Yeni kategori eklemek için bir form alanı sağlanmıştır.
- Kategoriler üzerinde yapılan değişiklikler anında veritabanına kaydedilmektedir.
- Panel yalnızca admin yetkisine sahip kullanıcılar tarafından erişilebilir.
- Yetkilendirme, JWT token üzerinden sağlanmaktadır ve kullanıcı rolü kontrol edilmektedir.
- Panel için
- ✅ | Ana express dosyası parçalara bölünecek.
routesklasörüne hedefler parça parça olarak ayırıldı.- Değişkenler bir
config.jsdosyasına taşındı.
- ✅ | Gider düzenlemesi yapıldığında tarih güncellenmiyor, düzeltilecek.
- Güncellenen veri de
datedeğeri güncel tarih ile güncelleniyor.
- Güncellenen veri de
- ✅ | Kategoriler veritabanında varsayılan olarak belirlenecek.
- Varsayılan kategoriler otomatik olarak veritabanına eklenmektedir.
- Uygulama başlatıldığında
Category.initializeDefaults()metodu çağrılarak varsayılan kategoriler kontrol edilir ve eksik olanlar eklenir. - Eğer kategoriler mevcutsa tekrar eklenmez.
- ✅ | Kullanıcı rolünü JWT yerine çerezlere şifrelenmiş olarak işlenmeli.
- Kullanıcı rolü,
cryptomodülü ve Express'in signed cookies özelliği kullanılarak çerezde güvenli (signed: true) bir şekilde tutulur. - Şifreleme ve çözme işlemleri için bir
secretKeykullanılmaktadır ve bu anahtar.envdosyasında saklanmaktadır. - Çerez içeriği değiştirilmeye çalışıldığında sunucu tarafından imzalama kontrolü yapılır ve geçersiz sayılır.
- Sunucu tarafında sadece imzası geçerli olan çerezler kabul edilir böylece kullanıcı çerez değerini değiştirerek rol yükseltemez.
- Kullanıcı rolü,
- ✅ | Kategorilere renk tanımlanması yapılacak.
- Kategori veritabanı modeline color değeri eklendi ve varsayılan değeri
.envdosyası üzerinden belirlendi. - Kategori yönetim paneline bir renk seçici (
<input type="color">) eklendi. - Kullanıcılar kategori eklerken bir renk seçebilir.
config.jsdosyasınaDEFAULT_CATEGORY_COLORdeğişkeni eklendi ve bu değişken kategoriye özel bir renk atanmadığında kullanılacak varsayılan rengi belirtir.- Grafiklerde her kategori atanmış renklerle temsil edilir. Eğer bir kategori için renk atanmadıysa varsayılan renk kullanılır.
/api/categoriesve/api/default-category-colorAPI'leri ile kategorilere atanmış renkler ve varsayılan renk istemciye sağlanır.- Kullanıcılar kategori yönetim panelinden kategorilere özel renkler atayabilir veya mevcut renkleri düzenleyebilir.
- Kategori veritabanı modeline color değeri eklendi ve varsayılan değeri
- ✅ | Kategori yönetiminde düzenleme paneli eklenecek.
- Kategori yönetimi
/categoriesolan hedefi/admin/categoriesolarak değiştirildi ve admin klasörüne taşındı. /admin/categories/edit/:idiçin GET ve POST hedefleri eklendi.- Düzenleme işlemleri için yeni bir form sayfası oluşturuldu.
- Kategori yönetimi
- ✅ |
viewsklasörü parçalara ayrılacak.- EJS dosyalarını kolay bulabilmek adına klasörlere ayrıştırıldı.
layout.ejsiçerisindeki navbar ve footerpartialsklasörüne taşındı.
- ✅ |
bcrypt.hash()metodundasaltingyapılacak.bcryptjskütüphanesindenargon2kütüphanesine geçildi.- Kayıt olma, giriş yapma ve şifre sıfırlamadaki şifreleme ve doğrulama işlemleri
argon2kütüphanesine uygun bir şekilde değiştirildi. - Şifreleme algoritması Avrupa Birliği standartlarına uygun hale getirildi.
bcryptjskütüphanesi projeden kaldıırldı.
- ✅ | Şifre sıfırlama için rate limit eklenecek.
express-rate-limitkütühanesi kuruldu.routes/password.jsiçerisinde rate limit için bir middleware oluşturuldu.- Bu middleware 15 dakika içerisinde üçten fazla deneme yapılırsa bu süre içerisinde daha fazla denemeye izin verilmiyor.
.envdosyasınaPASSWORD_RESET_RATE_LIMITvePASSWORD_RESET_MAX_ATTEMPTdeğişkenleri tanımlandı ve varsayılan değerleriutil/config.jsiçerisinde belirtildi.
- ✅ | Dashboard'da giderlerin sayfalanması.
- Kullanıcının giderleri sayfa başına 10 kayıt olacak şekilde listelenmektedir.
- Backend'de toplam gider sayısına göre toplam sayfa sayısı hesaplanmakta ve ilgili sayfa için veriler
skipvelimitile çekilmektedir. - Frontend'de sayfa numaraları, İlk, Önceki, Sonraki ve Son butonları ile kullanıcı farklı sayfalara geçiş yapabilmektedir.
- Aktif sayfa vurgulanmakta ve geçerli olmayan butonlar devre dışı bırakılmaktadır.
- Eğer kullanıcı giderleri yalnızca 1 sayfadan oluşuyorsa sayfalama bileşeni gösterilmemektedir.
- ✅ | Gönderilen e-postaları veritabanına loglama.
models/emailLog.jsadında yeni bir veritabanı modeli oluşturuldu.- E-posta alıcısı, konusu, gönderim durumu (başarılı/başarısız) ve hata mesajı gibi bilgiler kaydedilmektedir.
util/mail.jsiçerisinde gönderilen e-postaların kayıtları oluşturulmaktadır.- E-posta gönderimi başarılı olduğunda gönderim bilgileri success durumu ile loglanmaktadır.
- E-posta gönderimi başarısız olduğunda hata mesajı ile birlikte failure durumu loglanmaktadır.
- ✅ | NoSQL Injection koruması eklenecek.
express-mongo-sanitizekütüphanesi kuruldu ve NoSQL Injection koruması sağlandı.req.paramsüzerinden gelen ID'lerin geçerli bir MongoDB ObjectId olduğunun kontrolleri sağlandı.
- ✅ | Giderler dosya olarak dışa aktarılmalı.
- Kullanıcıların giderlerini Excel, PDF ve CSV formatlarında dışa aktarması sağlandı.
- ExcelJS kütüphanesi kullanılarak giderler bir Excel dosyasına yazılmakta ve kullanıcıya indirilebilir şekilde sunulmaktadır.
- PDFKit kütüphanesi ile giderler yazdırılabilir bir PDF raporu olarak oluşturulmaktadır. Türkçe karakter desteği için özel font kullanılmıştır.
- csv-writer kütüphanesi ile giderler bir CSV dosyasına dönüştürülmekte ve geçici dosya olarak oluşturulup indirme işlemi tamamlandıktan sonra silinmektedir.
- Kullanıcıların giderlerini JSON formatında dışa aktarması sağlandı.
- Her format için dosya adlandırma standardı uygulanmıştır (
giderler_YYYY-MM-DD.uzantı). - Kullanıcılar yalnızca kendi giderlerini dışa aktarabilmektedir.
- ✅ | Kayıt olan kullanıcılar log tutulacak.
models/authLog.jsadında bir veritabanı modeli oluşturuldu.- Kullanıcı kayıt işlemlerinde başarılı veya başarısız her deneme için log kaydı eklenmektedir.
- Loglarda kullanıcı ID'si, IP adresi, işlem türü (register), durum (success/fail) ve detay bilgileri tutulmaktadır.
- Kayıt işlemi başarılı olduğunda "Kullanıcı başarıyla kaydedildi." mesajı ile loglanır.
- Kayıt sırasında hata oluşursa hata mesajı ile birlikte log kaydı oluşturulur.
- Ayrıcı kullanıcıların giriş, çıkış ve şifre sıfırlama işlemleri de aynı kayıt işlemlerinde olduğu gibi log kaydı alınmaktadır.
- Bu sayede kullanıcı kayıt işlemleri izlenebilir ve olası hatalar kolayca tespit edilebilir.
- ✅ | Mobil görünüm için CSS iyileştirmeleri yapılacak.
- Sayfaların mobil görünümü daha düzenli hale getirilerek optimize edildi.
- ✖️ | Kullanıcılar birden fazla role sahip olabilmeli.
- ✖️ | Kategorilere alt kategoriler eklenecek.
- ✖️ | Kullanıcılar kendileri için kategoriler oluşturabilsin.
- ✖️ | Detaylı grafikler oluşturulacak.
- ✖️ | Hataları veritabanına loglama.
- ✖️ |
try-catchmantığı olmadan kullanımı araştırılacak. (async handler?) - ✖️ | Çoklu dil desteği eklenecek.
✅ Tamamlandı. | ⭕ Üzerinde çalışılıyor. | ✖️ Tamamlanmadı.