fixes 4
This commit is contained in:
parent
ee8b419887
commit
68edb2c3a1
@ -8,8 +8,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- /var/jenkins_home/logos:/root/FBLA24/fbla-api/logos
|
- /var/jenkins_home/logos:/root/FBLA24/fbla-api/logos
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_USERNAME
|
- JOBLINK_POSTGRES_USERNAME
|
||||||
- POSTGRES_PASSWORD
|
- JOBLINK_POSTGRES_PASSWORD
|
||||||
- SECRET_KEY
|
- JOBLINK_SECRET_KEY
|
||||||
- POSTGRES_ADDRESS
|
- JOBLINK_POSTGRES_ADDRESS
|
||||||
- POSTGRES_PORT
|
- JOBLINK_POSTGRES_PORT
|
||||||
@ -2,14 +2,14 @@ import 'dart:convert';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:argon2/argon2.dart';
|
||||||
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
|
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:postgres/postgres.dart';
|
import 'package:postgres/postgres.dart';
|
||||||
import 'package:shelf/shelf.dart';
|
import 'package:shelf/shelf.dart';
|
||||||
import 'package:shelf/shelf_io.dart' as io;
|
import 'package:shelf/shelf_io.dart' as io;
|
||||||
import 'package:shelf_router/shelf_router.dart';
|
import 'package:shelf_router/shelf_router.dart';
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
import 'package:argon2/argon2.dart';
|
|
||||||
|
|
||||||
|
|
||||||
SecretKey secretKey = SecretKey(Platform.environment['JOBLINK_SECRET_KEY']!);
|
SecretKey secretKey = SecretKey(Platform.environment['JOBLINK_SECRET_KEY']!);
|
||||||
|
|
||||||
@ -75,8 +75,7 @@ class Business {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String> fetchBusinessData() async {
|
Future<String> fetchBusinessData() async {
|
||||||
final result = await postgres.query(
|
final result = await postgres.query('''
|
||||||
'''
|
|
||||||
SELECT json_agg(
|
SELECT json_agg(
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id', id,
|
'id', id,
|
||||||
@ -92,8 +91,7 @@ Future<String> fetchBusinessData() async {
|
|||||||
'locationAddress', "locationAddress"
|
'locationAddress', "locationAddress"
|
||||||
)
|
)
|
||||||
) FROM businesses
|
) FROM businesses
|
||||||
'''
|
''');
|
||||||
);
|
|
||||||
|
|
||||||
var encoded = json.encode(result);
|
var encoded = json.encode(result);
|
||||||
var decoded = json.decode(encoded);
|
var decoded = json.decode(encoded);
|
||||||
@ -105,7 +103,6 @@ Future<String> fetchBusinessData() async {
|
|||||||
String _hostname = 'localhost';
|
String _hostname = 'localhost';
|
||||||
const _port = 8000;
|
const _port = 8000;
|
||||||
|
|
||||||
|
|
||||||
final postgres = PostgreSQLConnection(
|
final postgres = PostgreSQLConnection(
|
||||||
Platform.environment['JOBLINK_POSTGRES_ADDRESS']!,
|
Platform.environment['JOBLINK_POSTGRES_ADDRESS']!,
|
||||||
int.parse(Platform.environment['JOBLINK_POSTGRES_PORT']!),
|
int.parse(Platform.environment['JOBLINK_POSTGRES_PORT']!),
|
||||||
@ -114,8 +111,6 @@ final postgres = PostgreSQLConnection(
|
|||||||
password: Platform.environment['JOBLINK_POSTGRES_PASSWORD'],
|
password: Platform.environment['JOBLINK_POSTGRES_PASSWORD'],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
await postgres.open();
|
await postgres.open();
|
||||||
|
|
||||||
@ -162,15 +157,12 @@ void main() async {
|
|||||||
var json = jsonDecode(payload);
|
var json = jsonDecode(payload);
|
||||||
Business business = Business.fromJson(json);
|
Business business = Business.fromJson(json);
|
||||||
|
|
||||||
await postgres.query(
|
await postgres.query('''
|
||||||
'''
|
|
||||||
INSERT INTO businesses (name, description, type, website, "contactName", "contactPhone", "contactEmail", notes, "locationName", "locationAddress")
|
INSERT INTO businesses (name, description, type, website, "contactName", "contactPhone", "contactEmail", notes, "locationName", "locationAddress")
|
||||||
VALUES ('${business.name.replaceAll("'", "''")}', '${business.description.replaceAll("'", "''")}', '${business.type.name}', '${business.website}', '${business.contactName.replaceAll("'", "''")}', '${business.contactPhone}', '${business.contactEmail}', '${business.notes.replaceAll("'", "''")}', '${business.locationName.replaceAll("'", "''")}', '${business.locationAddress.replaceAll("'", "''")}')
|
VALUES ('${business.name.replaceAll("'", "''")}', '${business.description.replaceAll("'", "''")}', '${business.type.name}', '${business.website}', '${business.contactName.replaceAll("'", "''")}', '${business.contactPhone}', '${business.contactEmail}', '${business.notes.replaceAll("'", "''")}', '${business.locationName.replaceAll("'", "''")}', '${business.locationAddress.replaceAll("'", "''")}')
|
||||||
'''
|
''');
|
||||||
);
|
|
||||||
|
|
||||||
final dbBusiness = await postgres.query(
|
final dbBusiness = await postgres.query('''SELECT * FROM public.businesses
|
||||||
'''SELECT * FROM public.businesses
|
|
||||||
ORDER BY id DESC LIMIT 1''');
|
ORDER BY id DESC LIMIT 1''');
|
||||||
var id = dbBusiness[0][0];
|
var id = dbBusiness[0][0];
|
||||||
var logoResponse = await http.get(
|
var logoResponse = await http.get(
|
||||||
@ -198,7 +190,6 @@ void main() async {
|
|||||||
app.post('/fbla-api/deletebusiness', (Request request) async {
|
app.post('/fbla-api/deletebusiness', (Request request) async {
|
||||||
print('delete business request received');
|
print('delete business request received');
|
||||||
|
|
||||||
|
|
||||||
final payload = await request.readAsString();
|
final payload = await request.readAsString();
|
||||||
var auth = request.headers['Authorization']?.replaceAll('Bearer ', '');
|
var auth = request.headers['Authorization']?.replaceAll('Bearer ', '');
|
||||||
try {
|
try {
|
||||||
@ -206,17 +197,15 @@ void main() async {
|
|||||||
var json = jsonDecode(payload);
|
var json = jsonDecode(payload);
|
||||||
var id = json['id'];
|
var id = json['id'];
|
||||||
|
|
||||||
await postgres.query(
|
await postgres.query('''
|
||||||
'''
|
|
||||||
DELETE FROM public.businesses
|
DELETE FROM public.businesses
|
||||||
WHERE id IN
|
WHERE id IN
|
||||||
($id);
|
($id);
|
||||||
'''
|
''');
|
||||||
);
|
|
||||||
|
|
||||||
try{
|
try {
|
||||||
await File('logos/$id.png').delete();
|
await File('logos/$id.png').delete();
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
print('Failure to delete logo! $e');
|
print('Failure to delete logo! $e');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,13 +235,11 @@ void main() async {
|
|||||||
var json = jsonDecode(payload);
|
var json = jsonDecode(payload);
|
||||||
Business business = Business.fromJson(json);
|
Business business = Business.fromJson(json);
|
||||||
|
|
||||||
await postgres.query(
|
await postgres.query('''
|
||||||
'''
|
|
||||||
UPDATE businesses SET
|
UPDATE businesses SET
|
||||||
name = '${business.name.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, description = '${business.description.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, website = '${business.website}'::text, type = '${business.type.name}'::text, "contactName" = '${business.contactName.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "contactPhone" = '${business.contactPhone}'::text, "contactEmail" = '${business.contactEmail}'::text, notes = '${business.notes.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "locationName" = '${business.locationName.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "locationAddress" = '${business.locationAddress.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text WHERE
|
name = '${business.name.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, description = '${business.description.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, website = '${business.website}'::text, type = '${business.type.name}'::text, "contactName" = '${business.contactName.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "contactPhone" = '${business.contactPhone}'::text, "contactEmail" = '${business.contactEmail}'::text, notes = '${business.notes.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "locationName" = '${business.locationName.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "locationAddress" = '${business.locationAddress.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text WHERE
|
||||||
id = ${business.id};
|
id = ${business.id};
|
||||||
'''
|
''');
|
||||||
);
|
|
||||||
|
|
||||||
var logoResponse = await http.get(
|
var logoResponse = await http.get(
|
||||||
Uri.http('logo.clearbit.com', '/${business.website}'),
|
Uri.http('logo.clearbit.com', '/${business.website}'),
|
||||||
@ -260,15 +247,14 @@ void main() async {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await File('logos/${business.id}.png').delete();
|
await File('logos/${business.id}.png').delete();
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
print('Failure to delete logo! $e');
|
print('Failure to delete logo! $e');
|
||||||
}
|
}
|
||||||
if (logoResponse.headers.toString().contains('image/png')) {
|
if (logoResponse.headers.toString().contains('image/png')) {
|
||||||
await File('logos/${business.id}.png').writeAsBytes(logoResponse.bodyBytes);
|
await File('logos/${business.id}.png')
|
||||||
|
.writeAsBytes(logoResponse.bodyBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Response.ok(
|
return Response.ok(
|
||||||
business.id.toString(),
|
business.id.toString(),
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
@ -292,9 +278,8 @@ void main() async {
|
|||||||
var username = json['username'];
|
var username = json['username'];
|
||||||
var password = json['password'];
|
var password = json['password'];
|
||||||
|
|
||||||
var saltDb = await postgres.query(
|
var saltDb = await postgres
|
||||||
'SELECT salt FROM users WHERE username=\'$username\''
|
.query('SELECT salt FROM users WHERE username=\'$username\'');
|
||||||
);
|
|
||||||
if (saltDb.isEmpty) {
|
if (saltDb.isEmpty) {
|
||||||
return Response.unauthorized(
|
return Response.unauthorized(
|
||||||
'invalid username',
|
'invalid username',
|
||||||
@ -320,17 +305,13 @@ void main() async {
|
|||||||
argon2.generateBytes(passwordBytes, result);
|
argon2.generateBytes(passwordBytes, result);
|
||||||
var resultHex = result.toHexString();
|
var resultHex = result.toHexString();
|
||||||
|
|
||||||
var passwordHashDb = await postgres.query(
|
var passwordHashDb = await postgres
|
||||||
'SELECT password_hash FROM users WHERE username=\'$username\''
|
.query('SELECT password_hash FROM users WHERE username=\'$username\'');
|
||||||
);
|
|
||||||
var passwordHash = passwordHashDb[0][0].toString();
|
var passwordHash = passwordHashDb[0][0].toString();
|
||||||
|
|
||||||
if (passwordHash == resultHex) {
|
if (passwordHash == resultHex) {
|
||||||
|
|
||||||
final jwt = JWT(
|
final jwt = JWT(
|
||||||
{
|
{'username': username},
|
||||||
'username': username
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
final token = jwt.sign(secretKey);
|
final token = jwt.sign(secretKey);
|
||||||
try {
|
try {
|
||||||
@ -345,7 +326,6 @@ void main() async {
|
|||||||
token.toString(),
|
token.toString(),
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return Response.unauthorized(
|
return Response.unauthorized(
|
||||||
'invalid password',
|
'invalid password',
|
||||||
@ -367,7 +347,8 @@ void main() async {
|
|||||||
var password = json['password'];
|
var password = json['password'];
|
||||||
|
|
||||||
var r = Random.secure();
|
var r = Random.secure();
|
||||||
String randomSalt = String.fromCharCodes(List.generate(32, (index) => r.nextInt(33) + 89));
|
String randomSalt = String.fromCharCodes(
|
||||||
|
List.generate(32, (index) => r.nextInt(33) + 89));
|
||||||
final salt = randomSalt.toBytesLatin1();
|
final salt = randomSalt.toBytesLatin1();
|
||||||
|
|
||||||
var parameters = Argon2Parameters(
|
var parameters = Argon2Parameters(
|
||||||
@ -385,18 +366,15 @@ void main() async {
|
|||||||
argon2.generateBytes(passwordBytes, result);
|
argon2.generateBytes(passwordBytes, result);
|
||||||
var resultHex = result.toHexString();
|
var resultHex = result.toHexString();
|
||||||
|
|
||||||
postgres.query(
|
postgres.query('''
|
||||||
'''
|
|
||||||
INSERT INTO public.users (username, password_hash, salt)
|
INSERT INTO public.users (username, password_hash, salt)
|
||||||
VALUES ('$username', '$resultHex', '$randomSalt')
|
VALUES ('$username', '$resultHex', '$randomSalt')
|
||||||
'''
|
''');
|
||||||
);
|
|
||||||
|
|
||||||
return Response.ok(
|
return Response.ok(
|
||||||
username,
|
username,
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
);
|
);
|
||||||
|
|
||||||
} on JWTExpiredException {
|
} on JWTExpiredException {
|
||||||
print('JWT Expired');
|
print('JWT Expired');
|
||||||
} on JWTException catch (e) {
|
} on JWTException catch (e) {
|
||||||
@ -420,18 +398,15 @@ void main() async {
|
|||||||
var json = jsonDecode(payload);
|
var json = jsonDecode(payload);
|
||||||
var username = json['username'];
|
var username = json['username'];
|
||||||
|
|
||||||
postgres.query(
|
postgres.query('''
|
||||||
'''
|
|
||||||
DELETE FROM public.users
|
DELETE FROM public.users
|
||||||
WHERE username IN ('$username');
|
WHERE username IN ('$username');
|
||||||
'''
|
''');
|
||||||
);
|
|
||||||
|
|
||||||
return Response.ok(
|
return Response.ok(
|
||||||
username,
|
username,
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
);
|
);
|
||||||
|
|
||||||
} on JWTExpiredException {
|
} on JWTExpiredException {
|
||||||
print('JWT Expired');
|
print('JWT Expired');
|
||||||
} on JWTException catch (e) {
|
} on JWTException catch (e) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user