Add JWT auth for protected routes, add /reg endpoint, remove /user endpoints
This commit is contained in:
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -12,7 +12,7 @@ import '../models/log.dart';
|
|||||||
class DatabaseProvider {
|
class DatabaseProvider {
|
||||||
late Connection _dbConnection;
|
late Connection _dbConnection;
|
||||||
|
|
||||||
final Map<String, int> _shareLinks = {};
|
final Map<String, bool> _shareLinks = {};
|
||||||
final _uuid = const Uuid();
|
final _uuid = const Uuid();
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
@@ -79,11 +79,9 @@ class DatabaseProvider {
|
|||||||
Sql.named('''
|
Sql.named('''
|
||||||
CREATE TABLE IF NOT EXISTS geopositions (
|
CREATE TABLE IF NOT EXISTS geopositions (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
|
||||||
x_value DOUBLE PRECISION NOT NULL,
|
x_value DOUBLE PRECISION NOT NULL,
|
||||||
y_value DOUBLE PRECISION NOT NULL,
|
y_value DOUBLE PRECISION NOT NULL,
|
||||||
datetime TIMESTAMP NOT NULL DEFAULT NOW(),
|
last_update TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
lifetime INTERVAL NOT NULL,
|
|
||||||
expires_at TIMESTAMP NOT NULL
|
expires_at TIMESTAMP NOT NULL
|
||||||
)
|
)
|
||||||
'''),
|
'''),
|
||||||
@@ -204,24 +202,20 @@ class DatabaseProvider {
|
|||||||
// ==================== Geoposition operations ====================
|
// ==================== Geoposition operations ====================
|
||||||
|
|
||||||
Future<Geoposition> createPosition(
|
Future<Geoposition> createPosition(
|
||||||
int userId,
|
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y,
|
||||||
Duration lifetime,
|
|
||||||
) async {
|
) async {
|
||||||
final expiresAt = DateTime.now().add(lifetime);
|
final expiresAt = DateTime.now().add(const Duration(hours: 24));
|
||||||
|
|
||||||
final results = await _dbConnection.execute(
|
final results = await _dbConnection.execute(
|
||||||
Sql.named('''
|
Sql.named('''
|
||||||
INSERT INTO geopositions (user_id, x_value, y_value, datetime, lifetime, expires_at)
|
INSERT INTO geopositions (x_value, y_value, last_update, expires_at)
|
||||||
VALUES (@userId, @xValue, @yValue, NOW(), @lifetime, @expiresAt)
|
VALUES (@xValue, @yValue, NOW(), @expiresAt)
|
||||||
RETURNING id, user_id, x_value, y_value, datetime, lifetime, expires_at
|
RETURNING id, x_value, y_value, last_update, expires_at
|
||||||
'''),
|
'''),
|
||||||
parameters: {
|
parameters: {
|
||||||
'userId': userId,
|
|
||||||
'xValue': x,
|
'xValue': x,
|
||||||
'yValue': y,
|
'yValue': y,
|
||||||
'lifetime': _toInterval(lifetime),
|
|
||||||
'expiresAt': expiresAt.toIso8601String(),
|
'expiresAt': expiresAt.toIso8601String(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -229,34 +223,28 @@ class DatabaseProvider {
|
|||||||
final row = results.first;
|
final row = results.first;
|
||||||
return Geoposition(
|
return Geoposition(
|
||||||
id: int.parse(row[0].toString()),
|
id: int.parse(row[0].toString()),
|
||||||
userId: int.parse(row[1].toString()),
|
xValue: double.parse(row[1].toString()),
|
||||||
xValue: double.parse(row[2].toString()),
|
yValue: double.parse(row[2].toString()),
|
||||||
yValue: double.parse(row[3].toString()),
|
lastUpdate: DateTime.parse(row[3].toString()),
|
||||||
datetime: DateTime.parse(row[4].toString()),
|
expiresAt: DateTime.parse(row[4].toString()),
|
||||||
lifetime: lifetime,
|
|
||||||
expiresAt: DateTime.parse(row[6].toString()),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Geoposition> updatePosition(
|
Future<Geoposition> updatePosition(
|
||||||
int userId,
|
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y,
|
||||||
Duration lifetime,
|
|
||||||
) async {
|
) async {
|
||||||
final expiresAt = DateTime.now().add(lifetime);
|
final expiresAt = DateTime.now().add(const Duration(hours: 24));
|
||||||
|
|
||||||
final results = await _dbConnection.execute(
|
final results = await _dbConnection.execute(
|
||||||
Sql.named('''
|
Sql.named('''
|
||||||
INSERT INTO geopositions (user_id, x_value, y_value, datetime, lifetime, expires_at)
|
INSERT INTO geopositions (x_value, y_value, last_update, expires_at)
|
||||||
VALUES (@userId, @xValue, @yValue, NOW(), @lifetime, @expiresAt)
|
VALUES (@xValue, @yValue, NOW(), @expiresAt)
|
||||||
RETURNING id, user_id, x_value, y_value, datetime, lifetime, expires_at
|
RETURNING id, x_value, y_value, last_update, expires_at
|
||||||
'''),
|
'''),
|
||||||
parameters: {
|
parameters: {
|
||||||
'userId': userId,
|
|
||||||
'xValue': x,
|
'xValue': x,
|
||||||
'yValue': y,
|
'yValue': y,
|
||||||
'lifetime': _toInterval(lifetime),
|
|
||||||
'expiresAt': expiresAt.toIso8601String(),
|
'expiresAt': expiresAt.toIso8601String(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -264,25 +252,22 @@ class DatabaseProvider {
|
|||||||
final row = results.first;
|
final row = results.first;
|
||||||
return Geoposition(
|
return Geoposition(
|
||||||
id: int.parse(row[0].toString()),
|
id: int.parse(row[0].toString()),
|
||||||
userId: int.parse(row[1].toString()),
|
xValue: double.parse(row[1].toString()),
|
||||||
xValue: double.parse(row[2].toString()),
|
yValue: double.parse(row[2].toString()),
|
||||||
yValue: double.parse(row[3].toString()),
|
lastUpdate: DateTime.parse(row[3].toString()),
|
||||||
datetime: DateTime.parse(row[4].toString()),
|
expiresAt: DateTime.parse(row[4].toString()),
|
||||||
lifetime: lifetime,
|
|
||||||
expiresAt: DateTime.parse(row[6].toString()),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Geoposition?> getLatestPosition(int userId) async {
|
Future<Geoposition?> getLatestPosition() async {
|
||||||
final results = await _dbConnection.execute(
|
final results = await _dbConnection.execute(
|
||||||
Sql.named('''
|
Sql.named('''
|
||||||
SELECT id, user_id, x_value, y_value, datetime, lifetime, expires_at
|
SELECT id, x_value, y_value, last_update, expires_at
|
||||||
FROM geopositions
|
FROM geopositions
|
||||||
WHERE user_id = @userId AND expires_at > NOW()
|
WHERE expires_at > NOW()
|
||||||
ORDER BY datetime DESC
|
ORDER BY last_update DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
'''),
|
'''),
|
||||||
parameters: {'userId': userId},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (results.isEmpty) return null;
|
if (results.isEmpty) return null;
|
||||||
@@ -290,13 +275,10 @@ class DatabaseProvider {
|
|||||||
final row = results.first;
|
final row = results.first;
|
||||||
return Geoposition(
|
return Geoposition(
|
||||||
id: int.parse(row[0].toString()),
|
id: int.parse(row[0].toString()),
|
||||||
userId: int.parse(row[1].toString()),
|
xValue: double.parse(row[1].toString()),
|
||||||
xValue: double.parse(row[2].toString()),
|
yValue: double.parse(row[2].toString()),
|
||||||
yValue: double.parse(row[3].toString()),
|
lastUpdate: DateTime.parse(row[3].toString()),
|
||||||
datetime: DateTime.parse(row[4].toString()),
|
expiresAt: DateTime.parse(row[4].toString()),
|
||||||
lifetime: Duration(
|
|
||||||
seconds: int.tryParse(row[5].toString()) ?? 0),
|
|
||||||
expiresAt: DateTime.parse(row[6].toString()),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,14 +290,14 @@ class DatabaseProvider {
|
|||||||
|
|
||||||
// ==================== Share operations ====================
|
// ==================== Share operations ====================
|
||||||
|
|
||||||
String createShareId(int userId) {
|
String createShareId() {
|
||||||
final uniqueId = _uuid.v4();
|
final uniqueId = _uuid.v4();
|
||||||
_shareLinks[uniqueId] = userId;
|
_shareLinks[uniqueId] = true;
|
||||||
return uniqueId;
|
return uniqueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int? getUserIdByShareId(String uniqueId) {
|
bool isValidShareId(String uniqueId) {
|
||||||
return _shareLinks[uniqueId];
|
return _shareLinks[uniqueId] == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Log operations ====================
|
// ==================== Log operations ====================
|
||||||
@@ -349,8 +331,4 @@ class DatabaseProvider {
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
String _toInterval(Duration duration) {
|
|
||||||
final seconds = duration.inSeconds;
|
|
||||||
return '$seconds seconds';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -6,11 +6,9 @@ CREATE TABLE IF NOT EXISTS users (
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS geopositions (
|
CREATE TABLE IF NOT EXISTS geopositions (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
|
||||||
x_value DOUBLE PRECISION NOT NULL,
|
x_value DOUBLE PRECISION NOT NULL,
|
||||||
y_value DOUBLE PRECISION NOT NULL,
|
y_value DOUBLE PRECISION NOT NULL,
|
||||||
datetime TIMESTAMP NOT NULL DEFAULT NOW(),
|
last_update TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
lifetime INTERVAL NOT NULL,
|
|
||||||
expires_at TIMESTAMP NOT NULL
|
expires_at TIMESTAMP NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import 'package:shelf/shelf.dart';
|
||||||
|
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
|
||||||
|
import 'package:dotenv/dotenv.dart';
|
||||||
|
|
||||||
|
class AuthMiddleware {
|
||||||
|
final Handler handler;
|
||||||
|
|
||||||
|
AuthMiddleware(this.handler);
|
||||||
|
|
||||||
|
Future<Response> call(Request request) async {
|
||||||
|
final authorization = request.headers['authorization'];
|
||||||
|
|
||||||
|
if (authorization == null || !authorization.startsWith('Bearer ')) {
|
||||||
|
return Response(401, body: 'Authorization header missing or invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
final token = authorization.substring(7);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final dotenv = DotEnv();
|
||||||
|
final secret = dotenv['JWT_SECRET'] ?? '';
|
||||||
|
final decoded = JWT.verify(token, SecretKey(secret));
|
||||||
|
|
||||||
|
return handler(request);
|
||||||
|
} catch (e) {
|
||||||
|
return Response(401, body: 'Invalid or expired token');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,15 @@
|
|||||||
class Geoposition {
|
class Geoposition {
|
||||||
final int id;
|
final int id;
|
||||||
final int userId;
|
|
||||||
final double xValue;
|
final double xValue;
|
||||||
final double yValue;
|
final double yValue;
|
||||||
final DateTime datetime;
|
final DateTime lastUpdate;
|
||||||
final Duration lifetime;
|
|
||||||
final DateTime expiresAt;
|
final DateTime expiresAt;
|
||||||
|
|
||||||
Geoposition({
|
Geoposition({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.userId,
|
|
||||||
required this.xValue,
|
required this.xValue,
|
||||||
required this.yValue,
|
required this.yValue,
|
||||||
required this.datetime,
|
required this.lastUpdate,
|
||||||
required this.lifetime,
|
|
||||||
required this.expiresAt,
|
required this.expiresAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -22,7 +18,7 @@ class Geoposition {
|
|||||||
'id': id,
|
'id': id,
|
||||||
'x': xValue,
|
'x': xValue,
|
||||||
'y': yValue,
|
'y': yValue,
|
||||||
'datetime': datetime.toIso8601String(),
|
'lastUpdate': lastUpdate.toIso8601String(),
|
||||||
'remainingSeconds': expiresAt.difference(DateTime.now()).inSeconds,
|
'remainingSeconds': expiresAt.difference(DateTime.now()).inSeconds,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -30,11 +26,9 @@ class Geoposition {
|
|||||||
factory Geoposition.fromMap(Map<String, dynamic> map) {
|
factory Geoposition.fromMap(Map<String, dynamic> map) {
|
||||||
return Geoposition(
|
return Geoposition(
|
||||||
id: map['id'],
|
id: map['id'],
|
||||||
userId: map['user_id'],
|
|
||||||
xValue: map['x_value'].toDouble(),
|
xValue: map['x_value'].toDouble(),
|
||||||
yValue: map['y_value'].toDouble(),
|
yValue: map['y_value'].toDouble(),
|
||||||
datetime: map['datetime'] as DateTime,
|
lastUpdate: map['last_update'] as DateTime,
|
||||||
lifetime: Duration(seconds: map['lifetime']),
|
|
||||||
expiresAt: map['expires_at'] as DateTime,
|
expiresAt: map['expires_at'] as DateTime,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import 'package:shelf/shelf.dart';
|
import 'package:shelf/shelf.dart';
|
||||||
import 'package:shelf_router/shelf_router.dart';
|
import 'package:shelf_router/shelf_router.dart';
|
||||||
import 'package:bcrypt/bcrypt.dart';
|
import 'package:bcrypt/bcrypt.dart';
|
||||||
|
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
|
||||||
|
import 'package:dotenv/dotenv.dart';
|
||||||
import '../database/database_provider.dart';
|
import '../database/database_provider.dart';
|
||||||
|
import '../middleware/auth_middleware.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
class AuthRoutes {
|
class AuthRoutes {
|
||||||
@@ -12,7 +15,8 @@ class AuthRoutes {
|
|||||||
Router get routes {
|
Router get routes {
|
||||||
final router = Router();
|
final router = Router();
|
||||||
router.post('/login', _login);
|
router.post('/login', _login);
|
||||||
router.get('/watch', _watch);
|
router.post('/reg', _register);
|
||||||
|
router.get('/watch', AuthMiddleware(_watch).call);
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,19 +33,40 @@ class AuthRoutes {
|
|||||||
return Response(401, body: 'Invalid credentials');
|
return Response(401, body: 'Invalid credentials');
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response(200, body: jsonEncode({'user': user.toMap()}));
|
// Генерация JWT токена
|
||||||
|
final dotenv = DotEnv();
|
||||||
|
final secret = dotenv['JWT_SECRET'] ?? '';
|
||||||
|
final jwt = JWT(
|
||||||
|
{'user_id': user.id, 'login': user.login},
|
||||||
|
issuer: 'family_safety_tracker'
|
||||||
|
);
|
||||||
|
final token = jwt.sign(SecretKey(secret));
|
||||||
|
|
||||||
|
return Response(200, body: jsonEncode({
|
||||||
|
'user': user.toMap(),
|
||||||
|
'token': token
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response> _register(Request request) async {
|
||||||
|
final body = await request.readAsString();
|
||||||
|
final data = jsonDecode(body);
|
||||||
|
|
||||||
|
final login = data['login'];
|
||||||
|
final password = data['password'];
|
||||||
|
|
||||||
|
final user = await database.createUser(login, password);
|
||||||
|
return Response(201, body: jsonEncode(user.toMap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> _watch(Request request) async {
|
Future<Response> _watch(Request request) async {
|
||||||
final uniqueId = request.url.queryParameters['unique_id'];
|
final uniqueId = request.url.queryParameters['unique_id'];
|
||||||
|
|
||||||
final userId = database.getUserIdByShareId(uniqueId!);
|
if (!database.isValidShareId(uniqueId!)) {
|
||||||
|
|
||||||
if (userId == null) {
|
|
||||||
return Response(404, body: 'Share link not found');
|
return Response(404, body: 'Share link not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
final position = await database.getLatestPosition(userId);
|
final position = await database.getLatestPosition();
|
||||||
|
|
||||||
if (position == null) {
|
if (position == null) {
|
||||||
return Response(404, body: 'No position available');
|
return Response(404, body: 'No position available');
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:shelf/shelf.dart';
|
import 'package:shelf/shelf.dart';
|
||||||
import 'package:shelf_router/shelf_router.dart';
|
import 'package:shelf_router/shelf_router.dart';
|
||||||
import '../database/database_provider.dart';
|
import '../database/database_provider.dart';
|
||||||
|
import '../middleware/auth_middleware.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
class GeoRoutes {
|
class GeoRoutes {
|
||||||
@@ -10,9 +11,9 @@ class GeoRoutes {
|
|||||||
|
|
||||||
Router get routes {
|
Router get routes {
|
||||||
final router = Router();
|
final router = Router();
|
||||||
router.post('/geo', _createPosition);
|
router.post('/geo', AuthMiddleware(_createPosition).call);
|
||||||
router.put('/geo', _updatePosition);
|
router.put('/geo', AuthMiddleware(_updatePosition).call);
|
||||||
router.post('/share', _createShare);
|
router.post('/share', AuthMiddleware(_createShare).call);
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,13 +21,10 @@ class GeoRoutes {
|
|||||||
final body = await request.readAsString();
|
final body = await request.readAsString();
|
||||||
final data = jsonDecode(body);
|
final data = jsonDecode(body);
|
||||||
|
|
||||||
final userId = data['user_id'];
|
|
||||||
final x = data['x'];
|
final x = data['x'];
|
||||||
final y = data['y'];
|
final y = data['y'];
|
||||||
final lifetimeSeconds = data['lifetime'];
|
|
||||||
final lifetime = Duration(seconds: lifetimeSeconds);
|
|
||||||
|
|
||||||
final position = await database.createPosition(userId, x, y, lifetime);
|
final position = await database.createPosition(x, y);
|
||||||
return Response(201, body: position.toJson());
|
return Response(201, body: position.toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,22 +32,15 @@ class GeoRoutes {
|
|||||||
final body = await request.readAsString();
|
final body = await request.readAsString();
|
||||||
final data = jsonDecode(body);
|
final data = jsonDecode(body);
|
||||||
|
|
||||||
final userId = data['user_id'];
|
|
||||||
final x = data['x'];
|
final x = data['x'];
|
||||||
final y = data['y'];
|
final y = data['y'];
|
||||||
final lifetimeSeconds = data['lifetime'];
|
|
||||||
final lifetime = Duration(seconds: lifetimeSeconds);
|
|
||||||
|
|
||||||
final position = await database.updatePosition(userId, x, y, lifetime);
|
final position = await database.updatePosition(x, y);
|
||||||
return Response(200, body: position.toJson());
|
return Response(200, body: position.toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> _createShare(Request request) async {
|
Future<Response> _createShare(Request request) async {
|
||||||
final body = await request.readAsString();
|
final shareId = database.createShareId();
|
||||||
final data = jsonDecode(body);
|
|
||||||
|
|
||||||
final userId = data['user_id'];
|
|
||||||
final shareId = database.createShareId(userId);
|
|
||||||
|
|
||||||
return Response(200, body: jsonEncode({'share_id': shareId}));
|
return Response(200, body: jsonEncode({'share_id': shareId}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
import 'package:shelf/shelf.dart';
|
|
||||||
import 'package:shelf_router/shelf_router.dart';
|
|
||||||
import '../database/database_provider.dart';
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
class UserRoutes {
|
|
||||||
final DatabaseProvider database;
|
|
||||||
|
|
||||||
UserRoutes(this.database);
|
|
||||||
|
|
||||||
Router get routes {
|
|
||||||
final router = Router();
|
|
||||||
router.get('/user', _getAllUsers);
|
|
||||||
router.post('/user', _createUser);
|
|
||||||
router.put('/user/<id>', _updateUser);
|
|
||||||
router.delete('/user/<id>', _deleteUser);
|
|
||||||
return router;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Response> _getAllUsers(Request request) async {
|
|
||||||
final users = await database.getAllUsers();
|
|
||||||
return Response(200, body: jsonEncode(users.map((u) => u.toMap()).toList()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Response> _createUser(Request request) async {
|
|
||||||
final body = await request.readAsString();
|
|
||||||
final data = jsonDecode(body);
|
|
||||||
|
|
||||||
final login = data['login'];
|
|
||||||
final password = data['password'];
|
|
||||||
|
|
||||||
final user = await database.createUser(login, password);
|
|
||||||
return Response(201, body: jsonEncode(user.toMap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Response> _updateUser(Request request) async {
|
|
||||||
final id = int.parse(request.params['id']!);
|
|
||||||
|
|
||||||
final body = await request.readAsString();
|
|
||||||
final data = jsonDecode(body);
|
|
||||||
|
|
||||||
final login = data['login'];
|
|
||||||
final password = data['password'];
|
|
||||||
|
|
||||||
final user = await database.updateUser(id, login, password);
|
|
||||||
return Response(200, body: jsonEncode(user.toMap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Response> _deleteUser(Request request) async {
|
|
||||||
final id = int.parse(request.params['id']!);
|
|
||||||
await database.deleteUser(id);
|
|
||||||
return Response(204);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,6 @@ import 'package:shelf_router/shelf_router.dart';
|
|||||||
|
|
||||||
import 'database/database_provider.dart';
|
import 'database/database_provider.dart';
|
||||||
import 'routes/auth_routes.dart';
|
import 'routes/auth_routes.dart';
|
||||||
import 'routes/user_routes.dart';
|
|
||||||
import 'routes/geo_routes.dart';
|
import 'routes/geo_routes.dart';
|
||||||
|
|
||||||
void main(List<String> args) async {
|
void main(List<String> args) async {
|
||||||
@@ -19,12 +18,10 @@ void main(List<String> args) async {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final authRoutes = AuthRoutes(database);
|
final authRoutes = AuthRoutes(database);
|
||||||
final userRoutes = UserRoutes(database);
|
|
||||||
final geoRoutes = GeoRoutes(database);
|
final geoRoutes = GeoRoutes(database);
|
||||||
|
|
||||||
final router = Router()
|
final router = Router()
|
||||||
..mount('', authRoutes.routes.call)
|
..mount('', authRoutes.routes.call)
|
||||||
..mount('', userRoutes.routes.call)
|
|
||||||
..mount('', geoRoutes.routes.call)
|
..mount('', geoRoutes.routes.call)
|
||||||
..get('/', (Request req) => Response.ok('Family Safety Tracker API\n'));
|
..get('/', (Request req) => Response.ok('Family Safety Tracker API\n'));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user