Skip to content

Commit 65ee395

Browse files
committed
Updated project, removed unnecesarry bloat
-Documented MongoDB model uporabniki.js -Documented MongoDB model pomozneFunkcije.js -Removed Address, ZIP code & City input fields -Removed all about statistics
1 parent a4aca77 commit 65ee395

24 files changed

+310
-575
lines changed

app_api/models/uporabniki.js

Lines changed: 129 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@
1919
* value:
2020
* sporočilo: Uporabnika ne najdem v bazi
2121
*/
22-
23-
24-
25-
2622
/**
2723
* @swagger
2824
* components:
@@ -280,91 +276,133 @@
280276
* example:
281277
* sporočilo: cd
282278
*/
283-
const mongoose = require('mongoose');
284-
const crypto = require('crypto');
285-
const jwt = require('jsonwebtoken');
286-
287-
/**
288-
* @swagger
289-
* components:
290-
* schemas:
291-
* Uporabnik:
292-
* type: object
293-
* properties:
294-
* uporabniskoIme:
295-
* type: string
296-
* ePosta:
297-
* type: string
298-
* zgoscenaVrednost:
299-
* type: string
300-
* zetonZaObnavljanjeGesla:
301-
* type: string
302-
* default: obnovljeno
303-
* jeAdmin:
304-
* type: boolean
305-
* default: false
306-
* kraj:
307-
* type: string
308-
* default: Ljubljana
309-
* posta:
310-
* type: string
311-
* default: 1000
312-
* required:
313-
* - uporabniskoIme
314-
* - ePosta
315-
* - zgoscenaVrednost
316-
* - kraj
317-
* - posta
318-
*/
319-
320-
const uporabnikiSchema = new mongoose.Schema({
321-
uporabniskoIme: {type:String, required: true/*, unique: true*/},
322-
ePosta: {type:String, required: true, unique: true},
323-
nakljucnaVrednost: String,
324-
zgoscenaVrednost: {type:String, required:true},
325-
zetonZaObnavljanjeGesla: {type: String, "default":"obnovljeno"},
326-
jeAdmin: {type: Boolean, "default":false},
327-
naslov: String,
328-
kraj: {type: String, "default": "Ljubljana", required: true},
329-
posta: {type: Number, min:1000, max:9999,"default":1000, required: true}
330-
});
331-
332-
uporabnikiSchema.methods.nastaviGeslo = function(geslo){
333-
this.nakljucnaVrednost = crypto.randomBytes(16).toString('hex');
334-
this.zgoscenaVrednost = crypto.pbkdf2Sync(geslo, this.nakljucnaVrednost, 1000,64,'sha512').toString('hex');
335-
};
336-
uporabnikiSchema.methods.nastaviZeton = function(zeton){
337-
this.zetonZaObnavljanjeGesla = crypto.pbkdf2Sync(zeton, this.nakljucnaVrednost, 1000,64,'sha512').toString('hex');
338-
}
339-
uporabnikiSchema.methods.preveriZeton = function(zeton){
340-
let zetonZaObnavljanjeGesla = crypto.pbkdf2Sync(zeton,this.nakljucnaVrednost,1000,64,'sha512').toString('hex');
341-
return this.zetonZaObnavljanjeGesla == zetonZaObnavljanjeGesla;
342-
}
343-
344-
uporabnikiSchema.methods.preveriGeslo = function(geslo){
345-
let zgoscenaVrednost = crypto.pbkdf2Sync(geslo,this.nakljucnaVrednost,1000,64,'sha512').toString('hex');
346-
return this.zgoscenaVrednost == zgoscenaVrednost;
347-
};
348-
349-
uporabnikiSchema.methods.posodobiGeslo = function(staroGeslo, novoGeslo, ponoviNovoGeslo){
350-
351-
if(!(new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@€#\$%\^&\*])(?=.{8,})").test(novoGeslo)) || novoGeslo != ponoviNovoGeslo || !this.preveriGeslo(staroGeslo)){
352-
return false; //uporabnika obvesti, da je nekaj šlo narobe pa mu daj hinte naj preveri kaj je crknilo
353-
}
354-
this.nastaviGeslo(novoGeslo); //geslo uspešno spremenjeno
355-
return true;
356-
}
279+
const mongoose = require('mongoose'); //lažje delo z MongoDB bazo
280+
const crypto = require('crypto'); //uporaba za enosmerno zgoščevanje podatkov (geslo, žeton za obnavljanje gesla,..)
281+
const jwt = require('jsonwebtoken'); //generiranje JWT žetona za avtentikacijo uporabnika
282+
/**
283+
* @swagger
284+
* components:
285+
* schemas:
286+
* Uporabnik:
287+
* type: object
288+
* properties:
289+
* uporabniskoIme:
290+
* type: string
291+
* ePosta:
292+
* type: string
293+
* zgoscenaVrednost:
294+
* type: string
295+
* zetonZaObnavljanjeGesla:
296+
* type: string
297+
* default: obnovljeno
298+
* jeAdmin:
299+
* type: boolean
300+
* default: false
301+
* kraj:
302+
* type: string
303+
* default: Ljubljana
304+
* posta:
305+
* type: string
306+
* default: 1000
307+
* required:
308+
* - uporabniskoIme
309+
* - ePosta
310+
* - zgoscenaVrednost
311+
* - kraj
312+
* - posta
313+
*/
314+
//UPORABNIK
315+
//Shema uporabnika
316+
317+
const uporabnikiSchema = new mongoose.Schema({
318+
uporabniskoIme: {type:String, required: true, unique: true}, // uporabniško ime
319+
ePosta: {type:String, required: true, unique: true}, // e-pošta
320+
nakljucnaVrednost: String, // naključna vrednost, ki se generira za potrebe enosmernega zgoščevanja gesla in žetona za obnavljanje (unikatno)
321+
zgoscenaVrednost: {type:String, required:true}, // zgoščena vrednost gesla in naključne vrednosti, ki se dejansko preverja
322+
zetonZaObnavljanjeGesla: String, // žeton za obnavljanje gesla (zgoščena vrednost žetona in naključne vrednosti)
323+
jeAdmin: {type: Boolean, "default":false}, //informacija ali uporabnik je administrator
324+
jePotrjen: {type: Boolean, "default":false} //potrdimo, da je uporabnik legit
325+
});
357326

358-
uporabnikiSchema.methods.generirajJwt = function(){
359-
const datumPoteka = new Date();
360-
datumPoteka.setDate(datumPoteka.getDate()+7);
361-
return jwt.sign({
362-
_id: this._id,
363-
uporabniskoIme: this.uporabniskoIme,
364-
ePosta: this.ePosta,
365-
jeAdmin: this.jeAdmin,
366-
potek: parseInt(datumPoteka.getTime() / 1000, 10)
367-
}, process.env.JWT_GESLO);
368-
};
369-
uporabnikiSchema.methods.preveriAdmin = function() { return this.jeAdmin}; //securanje na strani apija za vsak slučaj
370-
mongoose.model('Uporabnik', uporabnikiSchema, 'Uporabniki');
327+
//Uporabnik si nastavi novo geslo, dobi tudi naključno vrednost
328+
//Vhod: novo geslo, ki ga določi uporabnik
329+
uporabnikiSchema.methods.nastaviGeslo = function(geslo){
330+
this.nakljucnaVrednost = crypto.randomBytes(16).toString('hex');
331+
this.zgoscenaVrednost = crypto.pbkdf2Sync(geslo, this.nakljucnaVrednost, 1000,64,'sha512').toString('hex');
332+
};
333+
//Uporabnik si avtomatsko ob registraciji (in prošnji nas) nastavi novo geslo, dobi tudi naključno vrednos
334+
//Vhod: zeton, ki se samodejno generira ob registraciji / prošnji za zahtevo za obnovo
335+
uporabnikiSchema.methods.nastaviZeton = function(zeton){
336+
this.zetonZaObnavljanjeGesla = crypto.pbkdf2Sync(zeton, this.nakljucnaVrednost, 1000,64,'sha512').toString('hex');
337+
}
338+
//Preverba veljavnosti žetona ob obnovi gesla in ga takoj nastavimo na novo vrednost
339+
//Vhod: zeton, ki se samodejno generira ob registraciji / prošnji za zahtevo za obnovo
340+
//Izhod: informacija ali je zgoščena vrednost žetona identična z našim žetonom (žeton + naključna vrednost)
341+
uporabnikiSchema.methods.preveriZeton = function(zeton){
342+
let jeUjemanje = this.zetonZaObnavljanjeGesla==crypto.pbkdf2Sync(zeton,this.nakljucnaVrednost,1000,64,'sha512').toString('hex');
343+
this.nastaviZeton();
344+
return jeUjemanje;
345+
346+
}
347+
//Preverba veljavnosti gesla ob prijavi
348+
//Vhod: geslo, ki ga vnesemo ob prijavi
349+
//Izhod: informacija ali je zgoščena vrednost gesla identična z našim geslo (geslo + naključna vrednost)
350+
uporabnikiSchema.methods.preveriGeslo = function(geslo){
351+
return this.zgoscenaVrednost == crypto.pbkdf2Sync(geslo,this.nakljucnaVrednost,1000,64,'sha512').toString('hex');
352+
};
353+
354+
//TODO:
355+
//PREVERI in NASTAVI daj v skupno (VSAKA svoja kategorija), bolj skalabilno metodo, razširi obstoječe
356+
/*uporabnikiSchema.methods.preveri = function(tipPodatka, vsebinaPodatka){
357+
358+
switch(tipPodatka){
359+
case "geslo" :
360+
361+
break;
362+
case "zeton" :
363+
364+
break;
365+
default:
366+
return false;
367+
}
368+
369+
}*/
370+
371+
//Potrdimo uporabnika (ali je mail veljaven), pokličemo ob potrditvi maila
372+
uporabnikiSchema.methods.potrdiUporabnika = function()
373+
{
374+
if(!this.jePotrjen){
375+
this.jePotrjen=true;
376+
}
377+
}
378+
379+
//Posodabljanje gesla na zahtevo uporabnika (preko računa), če novo geslo ustreza vzorcu & sta novo in ponovitev novega gesla enaki & in je staro geslo še veljavno
380+
//VHOD: staro geslo, ter 2x novo geslo
381+
//IZHOD: informacija, ali je bilo geslo uspešno spremenjeno
382+
uporabnikiSchema.methods.posodobiGeslo = function(staroGeslo, novoGeslo, ponoviNovoGeslo){
383+
384+
if(!(new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@€#\$%\^&\*])(?=.{8,})").test(novoGeslo)) || novoGeslo != ponoviNovoGeslo || !this.preveriGeslo(staroGeslo)){
385+
return false; //uporabnika obvesti, da je nekaj šlo narobe pa mu daj hinte naj preveri kaj je crknilo
386+
}
387+
this.nastaviGeslo(novoGeslo); //geslo uspešno spremenjeno
388+
return true;
389+
}
390+
391+
//Generiramo novi JWT, vsebovani so _id, uporabniško ime, e pošta, ali je administrator ter datum poteka
392+
//podpišemo z geslom v .env datoteki
393+
uporabnikiSchema.methods.generirajJwt = function(){
394+
const datumPoteka = new Date();
395+
datumPoteka.setDate(datumPoteka.getDate()+7);
396+
return jwt.sign({
397+
_id: this._id,
398+
uporabniskoIme: this.uporabniskoIme,
399+
ePosta: this.ePosta,
400+
jeAdmin: this.jeAdmin,
401+
potek: parseInt(datumPoteka.getTime() / 1000, 10)
402+
}, process.env.JWT_GESLO);
403+
};
404+
405+
//Preverimo ali je dotični uporabnik admninistrator
406+
//IZHOD: Informacija, ali je uporabnik administrator ali ne.....
407+
uporabnikiSchema.methods.preveriAdmin = function() { return this.jeAdmin}; //securanje na strani apija za vsak slučaj
408+
mongoose.model('Uporabnik', uporabnikiSchema, 'Uporabniki');

app_api/pomozneFunkcije.js

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
const nodemailer = require("nodemailer");
2-
const mongoose = require('mongoose');
3-
const Uporabnik = mongoose.model('Uporabnik');;
4-
1+
const nodemailer = require("nodemailer"); //nodemailer za pošiljanje e-pošte uporabnikom
2+
const {google} = require('googleapis'); //po možnosti se reši gulaga in zrihtaj nekaj drugega
3+
const mongoose = require('mongoose'); //lažje delo z MongoDB bazo
4+
const Uporabnik = mongoose.model('Uporabnik'); //model Uporabnik -> /app_api/models/uporabnik.js
55

6+
//ENOSTAVNE FUNKCIJE
7+
//Vrnemo uporabnika glede na to ali obstaja payload in ali je v tem payloadu ePosta ( payload = JWT)
8+
//Vhod: zahteva (payload - JWT -> epošta)
9+
//Izhod: objekt tipa uporabnik po mongoose modelu oz. null, če uporabnik ne obstaja v bazi
610
async function vrniUporabnika(req) {
711
if (req.payload && req.payload.ePosta) {
812
const uporabnik = Uporabnik.findOne({ePosta: req.payload.ePosta});
@@ -12,12 +16,17 @@ async function vrniUporabnika(req) {
1216
return null;
1317
}
1418
}
15-
19+
//Preverimo, če je uporabnik administrator
20+
//Vhod: objekt tipa uporabnik iz mongoose modela
21+
//Izhod: vrednost true/false glede na to ali uporabnik je
1622
function jeAdmin(uporabnik) {
1723
if (uporabnik.jeAdmin) return true;
1824
return false;
25+
//mogoče bi bilo smiselno, dati to v models
1926
}
20-
27+
//Generiramo naključni žeton sestavljen iz vzorca A-Za-z0-9
28+
//Vhod: dolžina končnega naključnega niza žetona, ki ga želimo imeti (privzeto 40)
29+
//Izhod: "naključen" niz znakov, dolg toliko, na kolikor določena je vhodna dolžina
2130
function generirajObnovitveniZeton(dolzina = 40){
2231
var rezultat = "";
2332
var znaki ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@@ -27,41 +36,69 @@ function generirajObnovitveniZeton(dolzina = 40){
2736
}
2837
return rezultat;
2938
}
30-
function posljiObnovitveniZeton(zeton = "" , ePosta ="")
31-
{
32-
if(zeton == "" || ePosta =="") return false;
3339

34-
var besediloPoste = `
35-
<p>Karjola ti je pripeljala link do obnovitve gesla</p>
36-
<p>Žeton "${zeton}" vneseš na strani, na katero te je preusmerilo spletno mesto</p>
37-
<p> Če nisi tega gesla zahteval(a) ti, to spročilo ignoriraj.</p>`;
38-
39-
let transporter = nodemailer.createTransport({
40-
service: 'gmail',
41-
auth:{
42-
user: process.env.POSILJATELJ,
43-
pass: process.env.POSILJATELJ_GESLO
40+
//EMAIL
41+
//Uporabniku pošljemu obnovitveni zeton
42+
//Vhod: generiran žeton za obnovitev gesla & email uporabnika na katerega se žeton pošlje
43+
//Izhod: vrednost true/false, glede na to, ali se je pošiljanje izvršilo uspešno oz. vrne se napaka pri pošiljanju
44+
async function posljiObnovitveniZeton(zeton = "" , ePosta =""){
45+
try{
46+
if(zeton == "" || ePosta =="") return false;
47+
48+
//Oauth2
49+
const googleOauth2Client = new google.auth.OAuth2(process.env.OAUTH2_CLIENT_ID, process.env.OAUTH2_CLIENT_SECRET,'https://developers.google.com/oauthplayground');
50+
googleOauth2Client.setCredentials({refresh_token: process.env.REFRESH_TOKEN})
51+
const dostopniZeton = await googleOauth2Client.getAccessToken();
52+
console.log(dostopniZeton);
53+
54+
var besediloPoste = `
55+
<p>Karjola ti je pripeljala link do obnovitve gesla</p>
56+
<p>Žeton "${zeton}" vneseš na strani, na katero te je preusmerilo spletno mesto</p>
57+
<p> Če nisi tega gesla zahteval(a) ti, to spročilo ignoriraj.</p>`;
58+
/*
59+
let transporter = nodemailer.createTransport({
60+
service: 'gmail',
61+
auth:{
62+
user: process.env.POSILJATELJ,
63+
pass: process.env.POSILJATELJ_GESLO
64+
}
65+
});*/
66+
let transporter = nodemailer.createTransport({
67+
service: 'gmail',
68+
auth:{
69+
type: 'OAuth2',
70+
user: process.env.POSILJATELJ,
71+
clientId: process.env.OAUTH2_CLIENT_ID,
72+
clientSecret: process.env.OAUTH2_CLIENT_SECRET,
73+
refresh_token: process.env.REFRESH_TOKEN,
74+
accessToken: dostopniZeton
75+
}
76+
});
77+
78+
let nastavitvePoste = {
79+
from: '"Karjola Support" <' + process.env.POSILJATELJ +'>',
80+
to: `${ePosta}`,
81+
subject: "Žeton za obnovitev gesla",
82+
text: "Evo tu maš žeton!",
83+
html: besediloPoste
4484
}
45-
});
46-
let nastavitvePoste = {
47-
from: '"Karjola Support" <' + process.env.POSILJATELJ +'>',
48-
to: `${ePosta}`,
49-
subject: "Žeton za obnovitev gesla",
50-
text: "Evo tu maš žeton!",
51-
html: besediloPoste
85+
const rezultat = await transporter.sendMail(nastavitvePoste);
86+
return rezultat;
87+
}catch(napaka){
88+
89+
90+
return napaka;
5291
}
53-
transporter.sendMail(nastavitvePoste, function(napaka,odgovor){
54-
if(napaka){
55-
console.log("Zgodila se je napaka");
56-
return false;
57-
}else{
58-
console.log("Sporočilo uspešno poslano");
59-
return true;
60-
}
61-
});
6292

63-
return true;
6493
}
94+
95+
//funkcije za validacijo
96+
97+
98+
99+
100+
101+
65102
module.exports = {
66103
generirajObnovitveniZeton,
67104
posljiObnovitveniZeton,

0 commit comments

Comments
 (0)