Auth passed

This commit is contained in:
Yasin İLKAYA 2025-12-20 20:16:13 +03:00
parent c8bbb47a72
commit 4e1f8d574b
17 changed files with 386 additions and 21 deletions

View File

@ -1,10 +1,17 @@
const {Application} = require("../core/server");
const Joi = require("joi");
const { PostDataProcess } = require("../core/postdata");
const User = require("../database/user");
Application.get("/", LoginPage);
Application.get("/login", LoginPage);
Application.get("/register", RegisterPage);
///Application.post("/login", Login);
Application.post("/register", PostDataProcess(), Register);
/**
* @param {import("express").Request} request
* @param {import("express").Response} response
@ -23,4 +30,62 @@ async function LoginPage(request, response)
async function RegisterPage(request, response)
{
response.render("register");
}
/**
* @param {import("express").Request} request
* @param {import("express").Response} response
*/
async function Register(request, response)
{
const schema = Joi.object({
name: Joi.string().min(2).max(30).required().error(new Error('Ad zorunludur ve 2 ile 30 karakter arasında olmalıdır.')),
surname: Joi.string().min(2).max(30).required().error(new Error('Soyad zorunludur ve 2 ile 30 karakter arasında olmalıdır.')),
email: Joi.string().email().required().error(new Error('Geçerli bir e-posta adresi giriniz.')),
password: Joi.string().min(6).max(20).required().error(new Error('Şifre zorunludur ve en az 6 karakter olmalıdır.')),
passwordverif: Joi.any().equal(Joi.ref("password")).required().error(new Error('Şifreler eşleşmiyor.'))
});
const {error} = schema.validate(request.body);
if(error)
{
return response.status(400).json({
status: "fail",
message: error.message
});
}
if(await User.hasUser(request.body.email))
{
return response.status(400).json({
status: "fail",
message: "E-Mail adresi zaten kullanılıyor."
});
}
let userid;
try{
userid = await User.createUser(
request.body.name,
request.body.surname,
request.body.email,
request.body.password
);
}catch{
return response.status(500).json({
status: "fail",
message: "Bir hata oluştu"
});
}
request.session.authendicated = true;
request.session.user_id = userid;
request.session.user = await User.getUser(userid);
return response.status(200).json({
status: "success",
message: "Kayıt işlemi başarılı, hesabınıza giriş yapabilirsiniz"
});
}

6
controllers/fallback.js Normal file
View File

@ -0,0 +1,6 @@
const {Application} = require("../core/server");
Application.use((req, res, next) => {
res.status(404).render("error/404")
});

11
core/postdata.js Normal file
View File

@ -0,0 +1,11 @@
const multer = require("multer");
const {Application} = require("./server.js");
const storage = multer.memoryStorage();
const upload = multer({
storage: storage,
limits: { fileSize: 5 * 1024 * 1024 } // Örn: Max 5MB sınırı
});
exports.PostDataProcess = () => upload.none();

View File

@ -10,7 +10,7 @@ process.nextTick(async ()=>{
try{
await DB.migrate.latest();
console.log("✅ Veritabanı tabloları kontrol edildi");
}catch{
}catch(err){
console.error("❌ Migration hatası:", err);
}
})

View File

@ -0,0 +1,18 @@
/**
* @param {import("knex").Knex} knex
*/
exports.up = function(knex) {
return knex.schema.createTable('events', (table) => {
table.increments('id').primary();
table.integer('owner_id').notNullable();
table.string("name").notNullable();
table.text("description").nullable();
table.integer("score").notNullable();
table.dateTime("created_at").defaultTo(knex.fn.now());
table.dateTime("deleted_at");
});
};
exports.down = function(knex) {
return knex.schema.dropTable('events');
};

View File

@ -0,0 +1,24 @@
/**
* @param {import("knex").Knex} knex
*/
exports.up = function(knex) {
return knex.schema.createTable('students', (table) => {
table.increments('id').primary();
table.integer('owner_id').notNullable();
table.string("name").notNullable();
table.string("surname").nullable();
table.string("studentno").nullable();
table.string("email").nullable();
table.string("gender").nullable();
table.dateTime("bithdate").nullable();
table.text("description").nullable();
table.dateTime("created_at").defaultTo(knex.fn.now());;
table.dateTime("update_at").defaultTo(knex.fn.now());;
table.dateTime("deleted_at");
});
};
exports.down = function(knex) {
return knex.schema.dropTable('students');
};

View File

@ -0,0 +1,20 @@
/**
* @param {import("knex").Knex} knex
*/
exports.up = function(knex) {
return knex.schema.createTable('student_events', (table) => {
table.increments('id').primary();
table.integer('owner_id').notNullable();
table.integer("student_id").notNullable();
table.integer("event_id").notNullable();
table.integer("score").notNullable();
table.dateTime("created_at").defaultTo(knex.fn.now());
table.dateTime("update_at").defaultTo(knex.fn.now());
table.dateTime("deleted_at");
});
};
exports.down = function(knex) {
return knex.schema.dropTable('students');
};

53
database/user.js Normal file
View File

@ -0,0 +1,53 @@
const crypto = require("node:crypto");
const DB = require("./connection");
exports.createUser = createUser;
exports.hasUser = hasUser;
exports.getUser = getUser;
async function createUser(
name,
surname,
email,
password
)
{
const [id] = await DB.table("users")
.insert({
name,
surname,
email,
password: sha256(password)
})
.returning("id");
return id;
}
async function hasUser(email)
{
let data = await DB.table("users")
.select("id")
.where("email",email)
.first();
return data != null;
}
async function getUser(id)
{
return await DB.table("users")
.where("id",id)
.first();getUser
}
function sha256(key)
{
return crypto.createHash("sha256").update(key).digest("hex");
}
/*
table.string('name').notNullable();
table.string('surname').notNullable();
table.string('email').unique().index();
table.string('password',255).notNullable();
table.dateTime("created_at").defaultTo(knex.fn.now());;
table.dateTime("update_at").defaultTo(knex.fn.now());;
table.dateTime("deleted_at");
*/

View File

@ -1,8 +1,9 @@
require('dotenv').config({quiet:true});
//require('dotenv').config({quiet:true});
require("./core/server");
require("./core/static");
require("./database/session");
require("./controllers/auth");
require("./controllers/auth");
require("./controllers/fallback");

83
package-lock.json generated
View File

@ -9,16 +9,81 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@types/joi": "^17.2.2",
"connect-session-knex": "^5.0.0",
"dotenv": "^17.2.3",
"ejs": "^3.1.10",
"express": "^5.2.1",
"express-session": "^1.18.2",
"joi": "^18.0.2",
"knex": "^3.1.0",
"multer": "^2.0.2",
"mysql": "^2.18.1"
}
},
"node_modules/@hapi/address": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-5.1.1.tgz",
"integrity": "sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==",
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^11.0.2"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@hapi/formula": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-3.0.2.tgz",
"integrity": "sha512-hY5YPNXzw1He7s0iqkRQi+uMGh383CGdyyIGYtB+W5N3KHPXoqychklvHhKCC9M3Xtv0OCs/IHw+r4dcHtBYWw==",
"license": "BSD-3-Clause"
},
"node_modules/@hapi/hoek": {
"version": "11.0.7",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.7.tgz",
"integrity": "sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==",
"license": "BSD-3-Clause"
},
"node_modules/@hapi/pinpoint": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.1.tgz",
"integrity": "sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q==",
"license": "BSD-3-Clause"
},
"node_modules/@hapi/tlds": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@hapi/tlds/-/tlds-1.1.4.tgz",
"integrity": "sha512-Fq+20dxsxLaUn5jSSWrdtSRcIUba2JquuorF9UW1wIJS5cSUwxIsO2GIhaWynPRflvxSzFN+gxKte2HEW1OuoA==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@hapi/topo": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-6.0.2.tgz",
"integrity": "sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==",
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^11.0.2"
}
},
"node_modules/@standard-schema/spec": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
"license": "MIT"
},
"node_modules/@types/joi": {
"version": "17.2.2",
"resolved": "https://registry.npmjs.org/@types/joi/-/joi-17.2.2.tgz",
"integrity": "sha512-vPvPwxn0Y4pQyqkEcMCJYxXCMYcrHqdfFX4SpF4zcqYioYexmDyxtM3OK+m/ZwGBS8/dooJ0il9qCwAdd6KFtA==",
"license": "MIT",
"dependencies": {
"joi": "*"
}
},
"node_modules/accepts": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
@ -775,6 +840,24 @@
"node": ">=10"
}
},
"node_modules/joi": {
"version": "18.0.2",
"resolved": "https://registry.npmjs.org/joi/-/joi-18.0.2.tgz",
"integrity": "sha512-RuCOQMIt78LWnktPoeBL0GErkNaJPTBGcYuyaBvUOQSpcpcLfWrHPPihYdOGbV5pam9VTWbeoF7TsGiHugcjGA==",
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/address": "^5.1.1",
"@hapi/formula": "^3.0.2",
"@hapi/hoek": "^11.0.7",
"@hapi/pinpoint": "^2.0.1",
"@hapi/tlds": "^1.1.1",
"@hapi/topo": "^6.0.2",
"@standard-schema/spec": "^1.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/knex": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz",

View File

@ -15,11 +15,13 @@
"license": "ISC",
"type": "commonjs",
"dependencies": {
"@types/joi": "^17.2.2",
"connect-session-knex": "^5.0.0",
"dotenv": "^17.2.3",
"ejs": "^3.1.10",
"express": "^5.2.1",
"express-session": "^1.18.2",
"joi": "^18.0.2",
"knex": "^3.1.0",
"multer": "^2.0.2",
"mysql": "^2.18.1"

24
views/error/404.ejs Normal file
View File

@ -0,0 +1,24 @@
<%-include("../partials/header.ejs") %>
<div class="error-container p-0">
<div class="container">
<div>
<div>
<img alt="" class="img-fluid" src="../assets/images/background/error-404.png">
</div>
<div class="mb-3">
<div class="row">
<div class="col-lg-8 offset-lg-2 ">
<p class="text-center text-secondary f-w-500 mt-5">
Aradığınız sayfayı bulamadık, bu sayfa artık mevcut olmayabilir veya linki yanlış almış olabilirsiniz
</p>
</div>
</div>
</div>
<a class="btn btn-lg btn-primary" href="/" role="button">
<i class="ti ti-home"></i>
Geri Dön
</a>
</div>
</div>
</div>
<%-include("../partials/footer.ejs") %>

View File

@ -20,11 +20,11 @@
</div>
<div class="mb-3">
<label class="form-label" for="emailId">E-Posta Adresiniz</label>
<input class="form-control" type="email" id="emailId">
<input class="form-control" type="email" id="emailId" autocomplete="email">
</div>
<div class="mb-3">
<label class="form-label" for="password">Şifreniz</label>
<input class="form-control" type="password" id="password">
<input class="form-control" placeholder="Şifreniz" type="password" min="6" max="20" required name="password" autocomplete="current-password">
</div>
<div>
<button class="btn btn-primary w-100" type="submit">Giriş Yap</button>

View File

@ -1,5 +1,4 @@
</div>
<script src="../assets/js/jquery-3.6.3.min.js"></script>
<script src="../assets/vendor/bootstrap/bootstrap.bundle.min.js"></script>
<script src="/assets/vendor/bootstrap/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -16,6 +16,7 @@
<link href="/assets/vendor/bootstrap/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="/assets/css/style.css" rel="stylesheet" type="text/css">
<link href="/assets/css/responsive.css" rel="stylesheet" type="text/css">
<script src="/assets/js/jquery-3.6.3.min.js"></script>
</head>
<body>
<div class="app-wrapper d-block">

View File

@ -11,32 +11,39 @@
</a>
</div>
<div class="form_container">
<form class="app-form">
<form class="app-form" method="post" action="/register" enctype="multipart/form-data" onsubmit="sendAjax(this);return false">
<div class="mb-3 text-center">
<h3>Yeni hesap oluşturun</h3>
<p>
EkoEtki; bireylerin doğaya yönelik tutumlarını objektif kriterlerle analiz eden ve çevresel farkındalığı dijital bir 'Doğa Puanı' ile somutlaştıran yenilikçi bir davranış ölçümleme sistemidir.
</p>
</div>
<div class="mb-3">
<label class="form-label">Username</label>
<input class="form-control" placeholder="Enter Your Username" type="text">
<div class="mt-1">
<span class="text-danger" id="validationError"></span>
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input class="form-control" placeholder="Enter Your Email" type="email">
<label class="form-label">İsminiz</label>
<input class="form-control" placeholder="İsminizi giriniz" type="text" required name="name" autocomplete="given-name">
</div>
<div class="mb-3">
<label class="form-label">Password</label>
<input class="form-control" placeholder="Enter Your Password" type="password">
<label class="form-label">Soyisminiz</label>
<input class="form-control" placeholder="İsminizi giriniz" type="text" name="surname" autocomplete="family-name">
</div>
<div class="mb-3 form-check">
<input class="form-check-input" id="formCheck1" type="checkbox">
<label class="form-check-label" for="formCheck1">remember me</label>
<div class="mb-3">
<label class="form-label">E-Posta Adresiniz</label>
<input class="form-control" placeholder="E-Posta Adresiniz" type="email" required name="email" autocomplete="email">
</div>
<div class="mb-3">
<label class="form-label">Şifreniz</label>
<input class="form-control" placeholder="Şifreniz" type="password" min="6" max="20" required name="password" autocomplete="new-password">
</div>
<div class="mb-3">
<label class="form-label">Şifreniz (tekrar)</label>
<input class="form-control" placeholder="Şifreniz" type="password" min="6" max="20" required name="passwordverif" autocomplete="new-password">
</div>
<div>
<a class="btn btn-primary w-100" href="index.html" role="button">Giriş Yap</a>
<a class="btn btn-primary w-100 mt-1" href="index.html" role="button">Kayıt Ol</a>
<button class="btn btn-primary w-100" type="submit">Kayıt Ol</button>
<a class="btn btn-primary w-100 mt-1" href="/login" role="button">Giriş Yap</a>
</div>
</form>
</div>
@ -46,4 +53,55 @@
</div>
</main>
</div>
<script>
function sendAjax(form)
{
blockui();
let formData = new FormData(form);
$.ajax({
url: "/register",
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function(response) {
ublockui();
if(response.status == "success")
{
window.location = "/login";
}else{
$("#validationError").text(response.message);
}
},
error: function(err) {
ublockui();
$("#validationError").text(err.responseJSON.message);
},
});
return false;
}
function blockui()
{
$('.login-form-container').block({
message: '<div class="loader-container-box"><div class="loader"></div></div>',
//timeout: 13000,
overlayCSS: {
backgroundColor: 'rgba(var(--dark), 0.8)',
opacity: 0.8,
borderRadius: 'var(--app-border-radius)',
cursor: 'wait'
},
css: {
border: 0,
padding: 0,
backgroundColor: 'transparent'
}
});
}
function ublockui()
{
$('.login-form-container').unblock()
}
</script>
<script src="/assets/vendor/block-ui/jquery.blockUI.js"></script>
<%-include("./partials/footer.ejs") %>