From 9116876f7bde88f8f8c1c17af657207ece7c9c0f Mon Sep 17 00:00:00 2001 From: drake Date: Thu, 13 Jun 2024 14:27:36 -0500 Subject: [PATCH] API Rewrite --- fbla-api/docker-compose.yml | 1 + fbla-api/lib/fbla_api.dart | 170 ++++++++++++++++++++++++------- fbla-api/test/fbla_api_test.dart | 1 - 3 files changed, 136 insertions(+), 36 deletions(-) diff --git a/fbla-api/docker-compose.yml b/fbla-api/docker-compose.yml index 8693f12..069a51f 100644 --- a/fbla-api/docker-compose.yml +++ b/fbla-api/docker-compose.yml @@ -3,6 +3,7 @@ version: '3' services: fbla_api: image: fbla-api + restart: unless-stopped ports: - "8000:8000" volumes: diff --git a/fbla-api/lib/fbla_api.dart b/fbla-api/lib/fbla_api.dart index 0769ec0..efae684 100644 --- a/fbla-api/lib/fbla_api.dart +++ b/fbla-api/lib/fbla_api.dart @@ -22,13 +22,12 @@ enum BusinessType { other, } -enum JobType { cashier, server, mechanic } +enum JobType { cashier, server, mechanic, other } class Business { int id; String name; String description; - BusinessType? type; String? website; String? contactName; String? contactEmail; @@ -41,7 +40,6 @@ class Business { {required this.id, required this.name, required this.description, - this.type, this.website, this.contactName, this.contactEmail, @@ -51,20 +49,10 @@ class Business { this.locationAddress}); factory Business.fromJson(Map json) { - bool typeValid = true; - try { - BusinessType.values.byName(json['type']); - } catch (e) { - typeValid = false; - } - return Business( id: json['id'], name: json['name'], description: json['description'], - type: typeValid - ? BusinessType.values.byName(json['type']) - : BusinessType.other, website: json['website'], contactName: json['contactName'], contactEmail: json['contactEmail'], @@ -77,19 +65,41 @@ class Business { } class JobListing { + String? id; + String? businessId; String name; String description; JobType type; - String wage; - String link; + String? wage; + String? link; - JobListing({ - required this.name, - required this.description, - required this.type, - required this.wage, - required this.link, - }); + JobListing( + {this.id, + this.businessId, + required this.name, + required this.description, + required this.type, + this.wage, + this.link}); + + factory JobListing.fromJson(Map json) { + bool typeValid = true; + try { + JobType.values.byName(json['type']); + } catch (e) { + typeValid = false; + } + + return JobListing( + id: json['id'], + businessId: json['businessId'], + name: json['name'], + description: json['description'], + type: typeValid ? JobType.values.byName(json['type']) : JobType.other, + wage: json['wage'], + link: json['link'], + ); + } } Future fetchBusinessData() async { @@ -156,9 +166,13 @@ void main() async { json_build_object( 'id', id, 'name', name, - 'description', description + 'description', description, + 'website', website, + 'contactEmail', "contactEmail", + 'contactPhone', "contactPhone", + 'locationName', "locationName" ) - ) FROM public.businesses WHERE id IN (SELECT id FROM public.listings WHERE type='${filters.elementAt(i)}') + ) FROM public.businesses WHERE id IN (SELECT "businessId" FROM public.listings WHERE type='${filters.elementAt(i)}') '''))[0][0]; if (postgresResult != null) { @@ -184,7 +198,6 @@ void main() async { 'id', b.id, 'name', b.name, 'description', b.description, - 'type', b.type, 'website', b.website, 'contactName', b."contactName", 'contactEmail', b."contactEmail", @@ -254,8 +267,8 @@ void main() async { Business business = Business.fromJson(json); await postgres.query(''' - 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("'", "''")}') + INSERT INTO businesses (name, description, website, "contactName", "contactPhone", "contactEmail", notes, "locationName", "locationAddress") + VALUES ('${business.name.replaceAll("'", "''")}', '${business.description.replaceAll("'", "''")}', '${business.website ?? 'NULL'}', '${business.contactName?.replaceAll("'", "''") ?? 'NULL'}', '${business.contactPhone ?? 'NULL'}', '${business.contactEmail ?? 'NULL'}', '${business.notes?.replaceAll("'", "''") ?? 'NULL'}', '${business.locationName?.replaceAll("'", "''") ?? 'NULL'}', '${business.locationAddress?.replaceAll("'", "''") ?? 'NULL'}') '''); final dbBusiness = await postgres.query('''SELECT * FROM public.businesses @@ -283,6 +296,40 @@ void main() async { headers: {'Access-Control-Allow-Origin': '*'}, ); }); + app.post('/fbla-api/createlisting', (Request request) async { + print('create business request received'); + + final payload = await request.readAsString(); + var auth = request.headers['Authorization']?.replaceAll('Bearer ', ''); + try { + JWT.verify(auth!, secretKey); + var json = jsonDecode(payload); + JobListing listing = JobListing.fromJson(json); + + await postgres.query(''' + INSERT INTO listings ("businessId", name, description, type, wage, link) + VALUES ('${listing.businessId}' '${listing.name.replaceAll("'", "''")}', '${listing.description.replaceAll("'", "''")}', '${listing.type.name}', '${listing.wage ?? 'NULL'}', '${listing.link?.replaceAll("'", "''") ?? 'NULL'}') + '''); + + final dbListing = await postgres.query('''SELECT id FROM public.listings + ORDER BY id DESC LIMIT 1'''); + var id = dbListing[0][0]; + + return Response.ok( + id.toString(), + headers: {'Access-Control-Allow-Origin': '*'}, + ); + } on JWTExpiredException { + print('JWT Expired'); + } on JWTException catch (e) { + print(e.message); + } + + return Response.unauthorized( + 'unauthorized', + headers: {'Access-Control-Allow-Origin': '*'}, + ); + }); app.post('/fbla-api/deletebusiness', (Request request) async { print('delete business request received'); @@ -293,11 +340,7 @@ void main() async { var json = jsonDecode(payload); var id = json['id']; - await postgres.query(''' - DELETE FROM public.businesses - WHERE id IN - ($id); - '''); + await postgres.query('DELETE FROM public.business WHERE id=$id;'); try { await File('logos/$id.png').delete(); @@ -320,6 +363,33 @@ void main() async { headers: {'Access-Control-Allow-Origin': '*'}, ); }); + app.post('/fbla-api/deletelisting', (Request request) async { + print('delete listing request received'); + + final payload = await request.readAsString(); + var auth = request.headers['Authorization']?.replaceAll('Bearer ', ''); + try { + JWT.verify(auth!, secretKey); + var json = jsonDecode(payload); + var id = json['id']; + + await postgres.query('DELETE FROM public.listings WHERE id=$id;'); + + return Response.ok( + id.toString(), + headers: {'Access-Control-Allow-Origin': '*'}, + ); + } on JWTExpiredException { + print('JWT Expired'); + } on JWTException catch (e) { + print(e.message); + } + + return Response.unauthorized( + 'unauthorized', + headers: {'Access-Control-Allow-Origin': '*'}, + ); + }); app.post('/fbla-api/editbusiness', (Request request) async { print('edit business request received'); @@ -333,7 +403,7 @@ void main() async { await postgres.query(''' 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, "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}; '''); @@ -366,6 +436,38 @@ void main() async { headers: {'Access-Control-Allow-Origin': '*'}, ); }); + app.post('/fbla-api/editlisting', (Request request) async { + print('edit listing request received'); + + final payload = await request.readAsString(); + var auth = request.headers['Authorization']?.replaceAll('Bearer ', ''); + try { + JWT.verify(auth!, secretKey); + + var json = jsonDecode(payload); + JobListing listing = JobListing.fromJson(json); + + await postgres.query(''' + UPDATE listings SET + "businessId" = ${listing.businessId}, name = '${listing.name.replaceAll("'", "''")}'::text, description = '${listing.description.replaceAll("'", "''")}'::text, type = '${listing.type.name}'::text, wage = '${listing.wage ?? 'NULL'}'::text, link = '${listing.link?.replaceAll("'", "''") ?? 'NULL'}'::text WHERE + id = ${listing.id}; + '''); + + return Response.ok( + listing.id.toString(), + headers: {'Access-Control-Allow-Origin': '*'}, + ); + } on JWTExpiredException { + print('JWT Expired'); + } on JWTException catch (e) { + print(e.message); + } + + return Response.unauthorized( + 'unauthorized', + headers: {'Access-Control-Allow-Origin': '*'}, + ); + }); app.post('/fbla-api/signin', (Request request) async { print('signin request received'); @@ -541,6 +643,4 @@ void main() async { final server = await io.serve(app, _hostname, _port); print('Serving at http://${server.address.host}:${server.port}'); - - // print((await postgres.query('select testdouble from public.test'))); } diff --git a/fbla-api/test/fbla_api_test.dart b/fbla-api/test/fbla_api_test.dart index c342365..5407e69 100644 --- a/fbla-api/test/fbla_api_test.dart +++ b/fbla-api/test/fbla_api_test.dart @@ -81,7 +81,6 @@ void main() async { "id": 0, "name": "tmp", "description": "tmp", - "type": "business", "website": "tmp", "contactName": "tmp", "contactEmail": "tmp",