basic login/logout
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
<i class="bi bi-wallet2 fs-4"></i>
|
<i class="bi bi-wallet2 fs-4"></i>
|
||||||
<h3 class="mb-0">{{ balance | currency}}</h3>
|
<h3 class="mb-0">{{ balance | currency}}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
<button type="button" (click)="logOut()" class="btn btn-outline-secondary">Log out</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { CommonModule, CurrencyPipe, DatePipe } from '@angular/common';
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { APIService } from '../../services/api';
|
import { APIService } from '../../services/api';
|
||||||
import Transaction from '@model/transaction';
|
import Transaction from '@model/transaction';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-screen-profile',
|
selector: 'app-screen-profile',
|
||||||
@@ -15,7 +16,10 @@ export class ScreenProfile implements OnInit{
|
|||||||
balance = 200;
|
balance = 200;
|
||||||
transactions!: Transaction[];
|
transactions!: Transaction[];
|
||||||
|
|
||||||
constructor(private api: APIService){}
|
constructor(
|
||||||
|
private api: APIService,
|
||||||
|
private router: Router,
|
||||||
|
){}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// FIXME transactions displaying delayed (only on second nav click)
|
// FIXME transactions displaying delayed (only on second nav click)
|
||||||
@@ -28,5 +32,15 @@ export class ScreenProfile implements OnInit{
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
logOut(){
|
||||||
|
this.api.logout().subscribe({
|
||||||
|
next: () => {
|
||||||
|
this.router.navigate(['login'])
|
||||||
|
},
|
||||||
|
error: (err) => {
|
||||||
|
console.error('Error logging out:', err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,4 +17,7 @@ export class APIService {
|
|||||||
login(username: string, password: string): Observable<any>{
|
login(username: string, password: string): Observable<any>{
|
||||||
return this.http.post(this.apiUrl + '/auth/login',{ 'username': username, 'password': password});
|
return this.http.post(this.apiUrl + '/auth/login',{ 'username': username, 'password': password});
|
||||||
}
|
}
|
||||||
|
logout(): Observable<any>{
|
||||||
|
return this.http.post(this.apiUrl + '/auth/logout', {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,22 +4,22 @@ import User from './user';
|
|||||||
@Table
|
@Table
|
||||||
export default class Transaction extends Model{
|
export default class Transaction extends Model{
|
||||||
@Column
|
@Column
|
||||||
amount!: number;
|
declare amount: number;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@ForeignKey(()=> User)
|
@ForeignKey(()=> User)
|
||||||
senderID!: string;
|
declare senderID: string;
|
||||||
|
|
||||||
@BelongsTo(() => User, 'senderID')
|
@BelongsTo(() => User, 'senderID')
|
||||||
sender!: User;
|
declare sender: User;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@ForeignKey(()=> User)
|
@ForeignKey(()=> User)
|
||||||
receiverID!: string;
|
declare receiverID: string;
|
||||||
|
|
||||||
@BelongsTo(() => User, 'receiverID')
|
@BelongsTo(() => User, 'receiverID')
|
||||||
receiver!: User;
|
declare receiver: User;
|
||||||
|
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
date!: Date;
|
declare date: Date;
|
||||||
}
|
}
|
||||||
@@ -4,18 +4,18 @@ import { Table, Column, Model, CreatedAt, DataType} from 'sequelize-typescript';
|
|||||||
export default class User extends Model{
|
export default class User extends Model{
|
||||||
|
|
||||||
@Column({primaryKey: true, unique: true, allowNull: false})
|
@Column({primaryKey: true, unique: true, allowNull: false})
|
||||||
userID!: string;
|
declare userID: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
displayName!: string;
|
declare displayName: string;
|
||||||
|
|
||||||
@Column(DataType.DECIMAL(20,2))
|
@Column(DataType.DECIMAL(20,2))
|
||||||
balance!: number;
|
declare balance: number;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
password!: string;
|
declare password: string;
|
||||||
|
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
creationDate!: Date;
|
declare creationDate: Date;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,28 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
import { logger } from '../util/logging';
|
||||||
|
import User from '../model/user';
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.post('/login', async (req, res) => {
|
router.post('/login', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
res.json('abc');
|
const { username, password } = req.body;
|
||||||
|
const user = await User.findOne({where: { userID: username}});
|
||||||
|
if (!user) return res.status(401).json({ message: 'Invalid credentials' });
|
||||||
|
const isMatch = (password == user.password);
|
||||||
|
//TODO hash passwords
|
||||||
|
//const isMatch = await bcrypt.compare(password, user.passwordHash);
|
||||||
|
if (!isMatch) return res.status(401).json({ message: 'Invalid credentials' });
|
||||||
|
res.json({ message: 'Logged in successfully' });
|
||||||
}catch (err) {
|
}catch (err) {
|
||||||
console.error('Failed to authenticate:', err);
|
logger.error('Failed to authenticate:', err);
|
||||||
res.status(500).json({ error: 'Failed to authenticate' });
|
res.status(500).json({ error: 'Failed to authenticate' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post('/logout', (req, res) => {
|
||||||
|
res.clearCookie('jwt');
|
||||||
|
res.json({ message: 'Logged out successfully' });
|
||||||
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
import { logger } from '../util/logging';
|
||||||
import Transaction from '../model/transaction';
|
import Transaction from '../model/transaction';
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@@ -8,7 +9,7 @@ router.get('/', async (req, res) => {
|
|||||||
const transactions = await Transaction.findAll({ limit: 10 });
|
const transactions = await Transaction.findAll({ limit: 10 });
|
||||||
res.json(transactions);
|
res.json(transactions);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch transactions:', err);
|
logger.error('Failed to fetch transactions:', err);
|
||||||
res.status(500).json({ error: 'Failed to fetch transactions' });
|
res.status(500).json({ error: 'Failed to fetch transactions' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user