From 64e7fd66fc5dc3e0694369659eba3cff8166acb8 Mon Sep 17 00:00:00 2001 From: Thom Werring Date: Tue, 26 Mar 2024 21:32:33 +0100 Subject: [PATCH] Added Authentication --- .dockerignore | 2 + .gitignore | 2 +- Dockerfile | 2 +- README.md | 18 ++- database/entrypoint/init.sql | 140 ++++++++++++++++++ package-lock.json | 24 +++ package.json | 9 +- track.http => requests.http | 8 + src/app.controller.ts | 21 --- src/app.module.ts | 54 ++++--- src/app.service.ts | 19 --- src/auth.service.ts | 28 ++++ src/entities/apiKey.entity.ts | 23 +++ src/guards/auth.guard.ts | 47 ++++++ src/shipments/shipments.controller.spec.ts | 22 --- src/shipments/shipments.controller.ts | 6 +- tests/shipments/shipments.controller.spec.ts | 36 +++++ .../shipments/shipments.service.spec.ts | 2 +- 18 files changed, 370 insertions(+), 93 deletions(-) create mode 100644 database/entrypoint/init.sql rename track.http => requests.http (52%) delete mode 100644 src/app.controller.ts delete mode 100644 src/app.service.ts create mode 100644 src/auth.service.ts create mode 100644 src/entities/apiKey.entity.ts create mode 100644 src/guards/auth.guard.ts delete mode 100644 src/shipments/shipments.controller.spec.ts create mode 100644 tests/shipments/shipments.controller.spec.ts rename {src => tests}/shipments/shipments.service.spec.ts (86%) diff --git a/.dockerignore b/.dockerignore index 94a1079..7a1f115 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,4 @@ +database +coverage tech-assignment-data node_modules diff --git a/.gitignore b/.gitignore index 93405f0..4c70595 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/database +/database/lib .eslintcache # compiled output diff --git a/Dockerfile b/Dockerfile index 6968709..a582196 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ WORKDIR /usr/src/app COPY package*.json . -RUN npm ci +RUN npm ci --no-auditdc po COPY . . diff --git a/README.md b/README.md index 65967dd..09aaedd 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# MyFreight Assessment + +## Receiving Tracking information +When receiving Tracking information, the following steps need to be completed to process the data ```mermaid flowchart TD receiveTracking(["Receive Tracking"]) @@ -26,8 +30,12 @@ containerNumber:**string** %% isArrivingSoon -->|yes| sendArriveSoon ``` -```mermaid -flowchart - getShipments([Get all shipments]) - -``` + +## Possible improvements + +- Sending the actual notification, there should be a more general way to setup notifiers +- Moving some variables to config files + - when is a shipment "arriving soon" + - database credentials (via an .env) + - mock date +- diff --git a/database/entrypoint/init.sql b/database/entrypoint/init.sql new file mode 100644 index 0000000..634171c --- /dev/null +++ b/database/entrypoint/init.sql @@ -0,0 +1,140 @@ +CREATE SCHEMA IF NOT EXISTS `myfreight` COLLATE 'utf8mb4_general_ci'; + +use `myfreight`; + +-- MySQL dump 10.13 Distrib 8.0.36, for Linux (x86_64) +-- +-- Host: 127.0.0.1 Database: myfreight +-- ------------------------------------------------------ +-- Server version 8.3.0 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `apiKeys` +-- + +DROP TABLE IF EXISTS `apiKeys`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `apiKeys` ( + `enabled` tinyint NOT NULL, + `digest` char(64) COLLATE utf8mb4_general_ci NOT NULL, + `apiKey` char(25) COLLATE utf8mb4_general_ci NOT NULL, + PRIMARY KEY (`apiKey`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `apiKeys` +-- + +LOCK TABLES `apiKeys` WRITE; +/*!40000 ALTER TABLE `apiKeys` DISABLE KEYS */; +INSERT INTO `apiKeys` VALUES (1,'43f94e272eb87c535148748e64c819a4a4206af692d79d537142ef9586614cd0','xngVvFikB0Sz64Qid6MBlQ2Vh'); +/*!40000 ALTER TABLE `apiKeys` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `containers` +-- + +DROP TABLE IF EXISTS `containers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `containers` ( + `id` binary(16) NOT NULL DEFAULT (uuid_to_bin(uuid())), + `containerNumber` char(13) COLLATE utf8mb4_general_ci NOT NULL, + `shipmentId` binary(16) NOT NULL, + PRIMARY KEY (`id`), + KEY `FK_c77186081e8668ee776fb3d96e7` (`shipmentId`), + CONSTRAINT `FK_c77186081e8668ee776fb3d96e7` FOREIGN KEY (`shipmentId`) REFERENCES `shipments` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `containers` +-- + +LOCK TABLES `containers` WRITE; +/*!40000 ALTER TABLE `containers` DISABLE KEYS */; +INSERT INTO `containers` VALUES (0x30313539346361632D353330392D3463,'EGLU744094804',0x62306663366364642D613663652D3434),(0x30333435663936612D316265312D3437,'EGLU357808841',0x36653965333066382D393730642D3462),(0x30356461656434322D366361642D3435,'MSCU838741443',0x34356232323564312D623135622D3465),(0x30356466356536312D363330622D3462,'MSCU682081815',0x62373365366266612D653233622D3439),(0x30363133353736652D303137372D3439,'MSCU950281892',0x36376163386439632D616262302D3433),(0x30363461373866632D656561322D3462,'MSCU585170557',0x36613934653133332D313831652D3464),(0x30373537633564642D663633652D3462,'MSCU852734339',0x30613639623331612D636438322D3432),(0x30373638363965362D373265342D3461,'MSCU895152286',0x34356232323564312D623135622D3465),(0x30376162616663372D633133382D3435,'EGLU572433273',0x32396132646130322D626261372D3464),(0x30386231343561662D383232322D3461,'EGLU232123920',0x62323538393966632D333662342D3438),(0x30393166323134382D313433342D3438,'MSCU121009815',0x30613639623331612D636438322D3432),(0x30393539393631612D313039622D3466,'MSCU580150891',0x61356365373438392D393436622D3430),(0x30396431323365622D353163362D3438,'MSCU152128640',0x31326139363931662D346561362D3439),(0x30626263393737302D353038352D3433,'MSCU373718036',0x61356365373438392D393436622D3430),(0x30626432653162302D623261312D3434,'MSCU215490559',0x64643162326363302D393038372D3464),(0x30626465316462662D613766362D3438,'MSCU860889242',0x62373365366266612D653233622D3439),(0x30633432346237362D396562372D3436,'EGLU151449672',0x38316539653863662D343562342D3430),(0x30636433613766642D346634332D3438,'MSCU139119833',0x30306432353565302D353666372D3465),(0x30636464373837322D636332642D3434,'EGLU162497707',0x37363630313536302D356665372D3466),(0x30666238633863642D633431642D3432,'EGLU369275736',0x36653965333066382D393730642D3462),(0x30666530633134332D646266382D3463,'EGLU556897276',0x38316539653863662D343562342D3430),(0x31303037643166342D633264342D3439,'MSCU817838853',0x63636533396237622D366232392D3439),(0x31303732363734622D303035302D3464,'EGLU474907721',0x32643862653936332D653837302D3464),(0x31326235316264662D303164642D3461,'EGLU176680217',0x62623264653661662D643530362D3462),(0x31333431616265632D356339632D3439,'EGLU281751984',0x38323862396566312D623638362D3465),(0x31343334656333322D353763382D3430,'MSCU400563513',0x30613639623331612D636438322D3432),(0x31373530613839622D336465352D3433,'MSCU195777241',0x30613639623331612D636438322D3432),(0x31376333323635332D623236332D3463,'EGLU845562787',0x63613465323738332D616261662D3439),(0x31393735373061302D633161322D3433,'EGLU375583963',0x62623264653661662D643530362D3462),(0x31623034386131622D323662612D3435,'EGLU320351392',0x32663437653538392D343432382D3462),(0x31636636633435362D343439392D3466,'EGLU769087792',0x62323538393966632D333662342D3438),(0x31643837373966662D366231372D3436,'MSCU372150274',0x61356365373438392D393436622D3430),(0x32326161393466642D663538372D3435,'MSCU770389113',0x62373365366266612D653233622D3439),(0x32336431363834312D643231612D3432,'MSCU528228880',0x62373365366266612D653233622D3439),(0x32343232366434312D343331382D3436,'EGLU747320390',0x39613561343033362D636230362D3462),(0x32346133396236392D316231612D3462,'MSCU902814586',0x66613733343633632D333862342D3466),(0x32356266333363332D316639632D3466,'EGLU996219285',0x39386463393462612D303639332D3431),(0x32383435633064632D633330372D3438,'EGLU443667287',0x39613561343033362D636230362D3462),(0x32393537333662302D653630642D3465,'MSCU798966571',0x66613733343633632D333862342D3466),(0x32626530363730382D356665632D3439,'EGLU239116248',0x37363630313536302D356665372D3466),(0x32633630653031312D313439652D3430,'MSCU582333105',0x63636533396237622D366232392D3439),(0x32636133353536622D643638382D3435,'MSCU974280032',0x39396363363961632D656464382D3462),(0x32646337623338612D336335652D3436,'EGLU267347752',0x66323732323232302D663536622D3433),(0x32653533323533322D623133662D3463,'EGLU714957620',0x64643563303131302D633164622D3433),(0x32653561656532352D333563392D3463,'MSCU751249378',0x34356232323564312D623135622D3465),(0x32653933366232622D383239362D3438,'EGLU653319761',0x61386131323764662D376539642D3439),(0x32656630636564392D613336362D3466,'MSCU984815691',0x31326139363931662D346561362D3439),(0x32663332666265642D323934322D3466,'EGLU295205359',0x32396132646130322D626261372D3464),(0x32663561646534392D393166662D3435,'MSCU586494912',0x37616138386138622D363339622D3464),(0x33303865326462302D626533312D3437,'MSCU919425251',0x31326139363931662D346561362D3439),(0x33306134333237352D363434622D3439,'MSCU477125834',0x66613733343633632D333862342D3466),(0x33313661363436662D633836372D3431,'EGLU740530335',0x64643563303131302D633164622D3433),(0x33323738393530312D343234652D3435,'EGLU794411636',0x38323862396566312D623638362D3465),(0x33326437316464332D663862612D3434,'EGLU501785820',0x36653965333066382D393730642D3462),(0x33326465353634342D663534352D3463,'EGLU900583170',0x33363635303364332D386264632D3434),(0x33353361653364302D383137322D3436,'EGLU304412665',0x38316539653863662D343562342D3430),(0x33353732316531312D663833362D3438,'EGLU437675852',0x34356166386138392D386530632D3439),(0x33363030653136612D656133382D3435,'MSCU218396090',0x34356232323564312D623135622D3465),(0x33363136616334382D323266342D3433,'EGLU244338113',0x62323538393966632D333662342D3438),(0x33366130616566662D343864632D3432,'EGLU589512453',0x66323732323232302D663536622D3433),(0x33643366363862632D643861632D3461,'MSCU512321925',0x30613639623331612D636438322D3432),(0x33643533363631622D613835352D3435,'EGLU851887320',0x34356166386138392D386530632D3439),(0x33653933323039612D336432342D3432,'MSCU750234192',0x39396363363961632D656464382D3462),(0x33656436613064632D613662332D3465,'MSCU602898754',0x66643065346139642D383062302D3431),(0x33663965326236362D376532372D3435,'EGLU112120534',0x34356166386138392D386530632D3439),(0x33666139386231382D326130332D3434,'EGLU502101315',0x32663437653538392D343432382D3462),(0x34306336386564382D356234622D3433,'EGLU127359343',0x38323862396566312D623638362D3465),(0x34313063386630352D393038342D3439,'MSCU495826476',0x31656466613939392D353635622D3462),(0x34313936633637342D373266612D3463,'MSCU406179033',0x32663631613733322D636233642D3431),(0x34323364626365642D663539302D3434,'EGLU866139144',0x38316539653863662D343562342D3430),(0x34326138383636372D646530332D3435,'MSCU382822978',0x62393437376630632D623166652D3434),(0x34326530336264332D326531352D3432,'MSCU996765558',0x32393031366466372D363066632D3437),(0x34343864336134612D373663372D3431,'EGLU727301375',0x61386131323764662D376539642D3439),(0x34346538636331382D343836392D3434,'MSCU864487401',0x32663631613733322D636233642D3431),(0x34353161613164622D656561392D3463,'MSCU311390393',0x30613639623331612D636438322D3432),(0x34363537333462652D633937392D3462,'MSCU492152756',0x36376163386439632D616262302D3433),(0x34633137626436322D613565332D3431,'EGLU333579040',0x64643563303131302D633164622D3433),(0x34633330613030322D346465372D3438,'EGLU884765190',0x65383131323737652D313937392D3437),(0x34653365383233322D656331362D3466,'EGLU489300965',0x32643862653936332D653837302D3464),(0x34656164643462352D633165662D3431,'EGLU169836642',0x64643563303131302D633164622D3433),(0x34656665363633322D633232662D3435,'MSCU580878022',0x34356232323564312D623135622D3465),(0x34663337346137622D373635362D3439,'EGLU814176835',0x37633535616166332D376338372D3431),(0x35306434663465382D376663612D3465,'EGLU147682510',0x37363630313536302D356665372D3466),(0x35306638643132332D623865642D3435,'EGLU996000030',0x37363630313536302D356665372D3466),(0x35313236633364332D323530642D3462,'MSCU840277910',0x32623034353230652D333735652D3438),(0x35313439356261352D613365352D3433,'MSCU884998214',0x63333963346162652D393361342D3433),(0x35316630323131352D336431322D3433,'EGLU828411108',0x32396132646130322D626261372D3464),(0x35316635633063352D616234312D3431,'EGLU794375469',0x37363630313536302D356665372D3466),(0x35323562333362622D306330332D3433,'EGLU378423578',0x33363635303364332D386264632D3434),(0x35343030336265612D303136372D3463,'MSCU901564472',0x36613934653133332D313831652D3464),(0x35343034386438312D323635352D3431,'EGLU428414886',0x32626665386639632D373063622D3461),(0x35346361373565322D623230332D3431,'EGLU806842302',0x62306663366364642D613663652D3434),(0x35353162646661612D303132642D3464,'EGLU907667339',0x39613561343033362D636230362D3462),(0x35376262383365382D353532642D3439,'EGLU516437809',0x33363635303364332D386264632D3434),(0x35376439373339662D356364642D3438,'MSCU399105827',0x30306432353565302D353666372D3465),(0x35383538336261652D323631322D3466,'EGLU993466859',0x61386131323764662D376539642D3439),(0x35393538383539642D613263302D3430,'EGLU327916463',0x38323862396566312D623638362D3465),(0x35613331643836352D633762362D3432,'MSCU626043284',0x30613639623331612D636438322D3432),(0x35616138613565632D333736312D3464,'EGLU691823139',0x39386463393462612D303639332D3431),(0x35626235336461322D346166362D3436,'EGLU693263704',0x37633535616166332D376338372D3431),(0x35636263303436342D643537342D3432,'MSCU900509206',0x30346632663931312D653238382D3466),(0x35636434373735312D613631382D3437,'MSCU957030749',0x39396363363961632D656464382D3462),(0x35653237303037362D366634342D3437,'EGLU860579212',0x37633535616166332D376338372D3431),(0x35653937323661312D393063392D3461,'EGLU611493415',0x62306663366364642D613663652D3434),(0x35666666313963342D353733332D3463,'MSCU752184078',0x61356365373438392D393436622D3430),(0x36333335393166612D656138312D3466,'MSCU120090041',0x36376163386439632D616262302D3433),(0x36336435626638342D653935342D3431,'EGLU448785834',0x32396132646130322D626261372D3464),(0x36343336306364622D343663662D3438,'MSCU122126969',0x66343265613731392D643865352D3465),(0x36353831326538372D353665612D3466,'MSCU846960833',0x64643162326363302D393038372D3464),(0x36353930336439322D643539622D3434,'EGLU440465522',0x61306634393161612D373339652D3437),(0x36363266623936392D336139652D3437,'EGLU950728272',0x61386131323764662D376539642D3439),(0x36393661616166662D666434632D3432,'EGLU261736156',0x36653965333066382D393730642D3462),(0x36396138376364322D643561302D3434,'EGLU412721924',0x32396132646130322D626261372D3464),(0x36396239623032332D633363362D3434,'MSCU587885419',0x61356365373438392D393436622D3430),(0x36623038383033612D306334302D3463,'MSCU945931124',0x63333963346162652D393361342D3433),(0x36626466383365392D373862642D3465,'MSCU216518046',0x31656466613939392D353635622D3462),(0x36636137393830632D343334362D3433,'MSCU662189529',0x32623034353230652D333735652D3438),(0x36636339386265342D393939392D3461,'MSCU808118805',0x31326139363931662D346561362D3439),(0x36636566656539612D626435652D3432,'MSCU117494170',0x66613733343633632D333862342D3466),(0x36656565343964302D396234392D3435,'EGLU215688462',0x62323538393966632D333662342D3438),(0x37333836656661632D396534342D3437,'EGLU130788267',0x64643563303131302D633164622D3433),(0x37336331313339622D613562352D3466,'MSCU271546856',0x63333963346162652D393361342D3433),(0x37343165376336332D356439372D3463,'MSCU936783114',0x31326139363931662D346561362D3439),(0x37343763303866612D633866652D3430,'MSCU813284326',0x30613530353064352D646337372D3439),(0x37346166343439362D333735362D3462,'MSCU243592930',0x39396363363961632D656464382D3462),(0x37363531323035352D656339632D3461,'MSCU857777574',0x63636533396237622D366232392D3439),(0x37386562353439382D353432382D3462,'EGLU955095606',0x39613561343033362D636230362D3462),(0x37396634616637392D373863352D3464,'EGLU669607696',0x36663562333866632D393361352D3466),(0x37623035303838312D376462362D3430,'MSCU264871157',0x31326139363931662D346561362D3439),(0x37623339323061652D303134642D3464,'EGLU768681385',0x39613561343033362D636230362D3462),(0x37646166386534342D313966372D3431,'MSCU157745447',0x32393031366466372D363066632D3437),(0x37646231396163652D363133622D3462,'EGLU597948476',0x32626665386639632D373063622D3461),(0x37653831633337362D383932362D3465,'EGLU826314841',0x63613465323738332D616261662D3439),(0x37656438613661322D643736302D3434,'EGLU606900664',0x32643862653936332D653837302D3464),(0x37663834626330652D396136632D3435,'EGLU218147648',0x66323732323232302D663536622D3433),(0x38326231373834652D383931362D3435,'EGLU647830767',0x32663437653538392D343432382D3462),(0x38333164316537322D323335612D3432,'EGLU700802543',0x36653965333066382D393730642D3462),(0x38343562356434322D376235662D3430,'EGLU359904988',0x32663437653538392D343432382D3462),(0x38346233643136322D623433362D3461,'EGLU628635097',0x63613465323738332D616261662D3439),(0x38353036313463352D653863622D3434,'MSCU437862599',0x30613639623331612D636438322D3432),(0x38353264633032652D353463352D3464,'EGLU523376757',0x66323732323232302D663536622D3433),(0x38373333353733382D663138392D3463,'EGLU987997664',0x36653965333066382D393730642D3462),(0x38613536373237332D353430662D3435,'MSCU775618233',0x66643065346139642D383062302D3431),(0x38626234363365382D663162342D3462,'EGLU195240500',0x32663437653538392D343432382D3462),(0x38633430333534352D383133312D3432,'EGLU566653495',0x64643563303131302D633164622D3433),(0x38653862666466662D626335312D3462,'MSCU177492712',0x33353863313561342D363535662D3434),(0x38663462393564622D356635312D3439,'MSCU212515254',0x30613530353064352D646337372D3439),(0x39303834393437302D636162302D3465,'EGLU779275590',0x32663437653538392D343432382D3462),(0x39316531613939612D613636612D3461,'MSCU193238631',0x31326139363931662D346561362D3439),(0x39316635316130372D653536612D3465,'EGLU660996256',0x32663437653538392D343432382D3462),(0x39343165336631352D633335332D3463,'EGLU240249473',0x33306530616261352D353266662D3437),(0x39356132366330322D363334612D3462,'EGLU301692229',0x38323862396566312D623638362D3465),(0x39356463393333392D393637312D3438,'EGLU222848526',0x64643563303131302D633164622D3433),(0x39386266346238612D316535612D3439,'MSCU922821825',0x37616138386138622D363339622D3464),(0x39386566613532612D313463612D3462,'EGLU775618788',0x65383131323737652D313937392D3437),(0x39396536613537372D366638302D3465,'EGLU468862907',0x65383131323737652D313937392D3437),(0x39613666613731312D643263652D3438,'EGLU315430165',0x62323538393966632D333662342D3438),(0x39623631613566382D396331322D3434,'EGLU455675703',0x32396132646130322D626261372D3464),(0x39633730363439392D373531652D3463,'EGLU805573301',0x38323862396566312D623638362D3465),(0x39643531353138312D326638642D3432,'MSCU735623127',0x63636533396237622D366232392D3439),(0x39643565653335332D396563632D3436,'EGLU268636042',0x65383131323737652D313937392D3437),(0x39656334326530322D306263662D3436,'MSCU513234615',0x32623034353230652D333735652D3438),(0x39663334303737612D323931372D3436,'EGLU640013625',0x39613561343033362D636230362D3462),(0x39666462393064612D643839392D3433,'EGLU749307461',0x62323538393966632D333662342D3438),(0x39666534396539332D626564332D3433,'EGLU796995806',0x32643862653936332D653837302D3464),(0x61303030643963392D373366322D3464,'EGLU325349089',0x62623264653661662D643530362D3462),(0x61316566663135302D353066372D3463,'MSCU958350356',0x39396363363961632D656464382D3462),(0x61323764393730382D303561612D3433,'MSCU545121997',0x31656466613939392D353635622D3462),(0x61333430393538332D303530312D3439,'EGLU616381113',0x65383131323737652D313937392D3437),(0x61333436343131332D323733372D3435,'MSCU574318126',0x32663631613733322D636233642D3431),(0x61333866366164662D636431312D3437,'EGLU555051823',0x34356166386138392D386530632D3439),(0x61343239656138392D346566302D3461,'EGLU108460914',0x62306663366364642D613663652D3434),(0x61346430343462322D613165612D3462,'MSCU240321187',0x63636533396237622D366232392D3439),(0x61353638633764612D313661352D3436,'EGLU152127630',0x32396132646130322D626261372D3464),(0x61363764313936652D656437392D3465,'MSCU803851087',0x36613934653133332D313831652D3464),(0x61373263303838372D373962302D3438,'EGLU214713301',0x33363635303364332D386264632D3434),(0x61373265356533382D656365312D3439,'MSCU190999377',0x62373365366266612D653233622D3439),(0x61376637636362332D613464322D3461,'EGLU587980844',0x32396132646130322D626261372D3464),(0x61383064346361622D356464322D3462,'EGLU352026438',0x34356166386138392D386530632D3439),(0x61396232623036312D653663392D3430,'EGLU522802603',0x36653965333066382D393730642D3462),(0x61613338383564392D353132352D3466,'EGLU386826265',0x34356166386138392D386530632D3439),(0x61616637376330382D633439322D3461,'EGLU741187161',0x61386131323764662D376539642D3439),(0x61626566326139622D376330322D3433,'MSCU468563069',0x61356365373438392D393436622D3430),(0x61633864313362302D373765642D3430,'MSCU975361884',0x62373365366266612D653233622D3439),(0x61636136623237642D383636322D3433,'EGLU644389135',0x32663437653538392D343432382D3462),(0x61636638623932332D306336392D3432,'EGLU155336540',0x32663437653538392D343432382D3462),(0x61653238653531382D623638362D3436,'MSCU236588326',0x30306432353565302D353666372D3465),(0x61656334363836302D663934392D3430,'MSCU261470038',0x32623034353230652D333735652D3438),(0x61656463386564362D633735352D3432,'MSCU367016604',0x66613733343633632D333862342D3466),(0x61663539303266352D663639352D3433,'MSCU668002797',0x61356365373438392D393436622D3430),(0x62313735613131312D626566312D3464,'MSCU383582561',0x30346632663931312D653238382D3466),(0x62313739643731612D376361352D3435,'EGLU516117310',0x61386131323764662D376539642D3439),(0x62326338336361312D646663332D3432,'MSCU175750384',0x34356232323564312D623135622D3465),(0x62336263646336362D303035382D3439,'EGLU288064024',0x62623264653661662D643530362D3462),(0x62336438643230612D656333612D3462,'MSCU552323954',0x63333963346162652D393361342D3433),(0x62343038376537382D356132612D3435,'MSCU768004665',0x36613934653133332D313831652D3464),(0x62353339653133322D346662332D3433,'EGLU325281773',0x62353035383036652D663834352D3432),(0x62356634333037312D663362352D3462,'MSCU799131354',0x39396363363961632D656464382D3462),(0x62373137663131612D646535342D3439,'EGLU739540440',0x33363635303364332D386264632D3434),(0x62373733303062632D383932352D3466,'EGLU615816350',0x66323732323232302D663536622D3433),(0x62383061636635662D396366352D3464,'MSCU286056924',0x36613934653133332D313831652D3464),(0x62383233613037332D323833332D3431,'EGLU947991215',0x37633535616166332D376338372D3431),(0x62383961386266642D666232632D3437,'EGLU686098105',0x65383131323737652D313937392D3437),(0x62386139363563642D346135312D3464,'MSCU973041910',0x36376163386439632D616262302D3433),(0x62393838653839642D313462662D3461,'MSCU681810924',0x36613934653133332D313831652D3464),(0x62613164623566332D363833652D3439,'EGLU286176949',0x64643563303131302D633164622D3433),(0x62613835376233322D363465392D3466,'MSCU267129297',0x66643065346139642D383062302D3431),(0x62613938313438312D333539342D3434,'EGLU417441160',0x38323862396566312D623638362D3465),(0x62626337356665622D373438302D3463,'MSCU278111555',0x31326139363931662D346561362D3439),(0x62633031626563312D373833362D3437,'MSCU272986180',0x66613733343633632D333862342D3466),(0x62633664626432652D613566382D3432,'MSCU188866519',0x31326139363931662D346561362D3439),(0x62646461613562662D386563352D3434,'MSCU833792906',0x63333963346162652D393361342D3433),(0x62646633376535612D663838322D3436,'MSCU742917665',0x31656466613939392D353635622D3462),(0x62653231393634392D396463322D3431,'EGLU895892712',0x39613561343033362D636230362D3462),(0x62653438393032612D656430342D3432,'MSCU108290255',0x61356365373438392D393436622D3430),(0x62666462326466312D376530392D3439,'EGLU492938944',0x66323732323232302D663536622D3433),(0x63313835326665312D623836372D3464,'EGLU143361803',0x63613465323738332D616261662D3439),(0x63316534383164612D626632392D3465,'EGLU576805959',0x62623264653661662D643530362D3462),(0x63326636386464632D623662392D3466,'EGLU426122954',0x37363630313536302D356665372D3466),(0x63333237616364662D326462342D3466,'MSCU149026207',0x30613639623331612D636438322D3432),(0x63333433633864382D303565332D3431,'EGLU240902631',0x62323538393966632D333662342D3438),(0x63346463373865302D633364362D3461,'EGLU370683789',0x37363630313536302D356665372D3466),(0x63353036373662612D663065652D3466,'EGLU180115893',0x33363635303364332D386264632D3434),(0x63363733393364332D386539382D3461,'EGLU403157185',0x62623264653661662D643530362D3462),(0x63363934656239612D353531622D3431,'EGLU165709362',0x32643862653936332D653837302D3464),(0x63366534316466642D353035322D3462,'EGLU432640700',0x38316539653863662D343562342D3430),(0x63373463323963342D613261382D3466,'MSCU684328239',0x30613639623331612D636438322D3432),(0x63396635333939312D363362362D3462,'MSCU770442043',0x62393437376630632D623166652D3434),(0x63616337353264652D393963642D3439,'EGLU652652946',0x64643563303131302D633164622D3433),(0x63623961613231342D626665332D3462,'EGLU772079113',0x34356166386138392D386530632D3439),(0x63643039616262322D346332392D3433,'EGLU940941753',0x62623264653661662D643530362D3462),(0x63643065313637362D623733632D3437,'EGLU459067015',0x38323862396566312D623638362D3465),(0x63646532303163332D353034312D3436,'EGLU167294020',0x33303263313165322D333832642D3464),(0x63653833366637312D653639322D3436,'EGLU641087378',0x32643862653936332D653837302D3464),(0x63663861333135652D363664362D3437,'MSCU160725794',0x62373365366266612D653233622D3439),(0x63663938623262652D326532652D3432,'MSCU402631730',0x66613733343633632D333862342D3466),(0x64313064636236622D633137622D3463,'EGLU556476019',0x33363635303364332D386264632D3434),(0x64323730313538642D383861392D3437,'EGLU320610473',0x63613465323738332D616261662D3439),(0x64333463393964312D653763622D3464,'EGLU713245569',0x39613561343033362D636230362D3462),(0x64336338383063312D623536642D3463,'MSCU867251651',0x36613934653133332D313831652D3464),(0x64366365646537392D336337372D3434,'MSCU821145506',0x62373365366266612D653233622D3439),(0x64373039306135352D343263662D3438,'EGLU227172535',0x66323732323232302D663536622D3433),(0x64376464366136372D343136652D3464,'EGLU502802203',0x38323862396566312D623638362D3465),(0x64396432663663392D626138352D3437,'EGLU663930473',0x39613561343033362D636230362D3462),(0x64623633643266362D636563392D3466,'EGLU755124873',0x62306663366364642D613663652D3434),(0x64636338396362342D333131342D3433,'MSCU724329835',0x36613934653133332D313831652D3464),(0x64643230373435382D373033322D3431,'EGLU628521067',0x66323732323232302D663536622D3433),(0x64643566613537352D643565632D3465,'EGLU935905704',0x37633535616166332D376338372D3431),(0x64653066653837622D623834302D3432,'MSCU954814759',0x64643162326363302D393038372D3464),(0x64663137636563632D643764362D3436,'EGLU626063129',0x62306663366364642D613663652D3434),(0x64666362656432642D306634372D3439,'MSCU730111991',0x39396363363961632D656464382D3462),(0x65306339336261622D663566312D3435,'EGLU854044930',0x37633535616166332D376338372D3431),(0x65313635666332632D383735332D3435,'EGLU950287184',0x34356166386138392D386530632D3439),(0x65326462663730642D306137302D3438,'EGLU275469869',0x66323732323232302D663536622D3433),(0x65336263343334312D333035612D3462,'EGLU204578516',0x37633535616166332D376338372D3431),(0x65343236346333622D353761342D3430,'EGLU241154670',0x62306663366364642D613663652D3434),(0x65353463303836632D303666352D3465,'EGLU751814900',0x62623264653661662D643530362D3462),(0x65353932393463382D656165392D3437,'MSCU912976334',0x63636533396237622D366232392D3439),(0x65393134363730382D643462352D3431,'MSCU941949890',0x61356365373438392D393436622D3430),(0x65613964626130652D326363612D3435,'EGLU685831930',0x66323732323232302D663536622D3433),(0x65623331303135342D643039652D3439,'EGLU179023961',0x32663437653538392D343432382D3462),(0x65623766346365312D353565632D3437,'EGLU157855796',0x34356166386138392D386530632D3439),(0x65636462643230612D386666382D3435,'MSCU382614851',0x34356232323564312D623135622D3465),(0x65643139363861662D336130612D3436,'EGLU790584008',0x62623264653661662D643530362D3462),(0x65656439613438382D613735312D3430,'EGLU505968184',0x38323862396566312D623638362D3465),(0x65656536303434372D376231612D3461,'MSCU396094465',0x64643162326363302D393038372D3464),(0x65663262306337662D646232372D3466,'EGLU790371728',0x39613561343033362D636230362D3462),(0x66303630323535632D653064612D3463,'MSCU396741377',0x66643065346139642D383062302D3431),(0x66303661643061652D656462302D3433,'EGLU953437570',0x36653965333066382D393730642D3462),(0x66303965363866662D643230302D3436,'EGLU167542883',0x33306530616261352D353266662D3437),(0x66306236346232642D336462362D3465,'MSCU684881884',0x32393031366466372D363066632D3437),(0x66323135326364612D396133642D3461,'EGLU463663631',0x32626665386639632D373063622D3461),(0x66336162343463332D616535662D3462,'MSCU969034244',0x62373365366266612D653233622D3439),(0x66343365646661302D396365382D3437,'MSCU573199255',0x32623034353230652D333735652D3438),(0x66356238316334662D643932622D3430,'EGLU899251157',0x33306530616261352D353266662D3437),(0x66366339353231622D316630642D3433,'MSCU770580442',0x32663631613733322D636233642D3431),(0x66373832656564662D383130392D3462,'EGLU821229696',0x64643563303131302D633164622D3433),(0x66393038396564642D336561642D3462,'EGLU745866509',0x61386131323764662D376539642D3439),(0x66396266666565642D623931652D3461,'EGLU668799754',0x32396132646130322D626261372D3464),(0x66613564396264632D333033352D3439,'EGLU184672068',0x34356166386138392D386530632D3439),(0x66616138323038382D636234362D3463,'MSCU565800252',0x34356232323564312D623135622D3465),(0x66623438633332612D613730312D3434,'MSCU491917381',0x66343265613731392D643865352D3465),(0x66633432343166362D326163392D3465,'EGLU492969972',0x36653965333066382D393730642D3462),(0x66633461373366392D613636382D3430,'MSCU369273828',0x63333963346162652D393361342D3433),(0x66633538316338662D373035632D3432,'EGLU640491844',0x38316539653863662D343562342D3430),(0x66633937336562392D383866642D3464,'MSCU521695247',0x31326139363931662D346561362D3439),(0x66636237326531382D356131392D3436,'MSCU530337918',0x32393031366466372D363066632D3437),(0x66646332376162392D653936322D3464,'EGLU172872958',0x62306663366364642D613663652D3434),(0x66646430313736652D616135612D3430,'MSCU216491664',0x34356232323564312D623135622D3465),(0x66656434386265332D396637382D3430,'MSCU273729412',0x31656466613939392D353635622D3462); +/*!40000 ALTER TABLE `containers` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `live_tracking` +-- + +DROP TABLE IF EXISTS `live_tracking`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `live_tracking` ( + `shipmentId` binary(16) NOT NULL, + `createdAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `latitude` decimal(11,7) NOT NULL, + `longitude` decimal(11,7) NOT NULL, + PRIMARY KEY (`shipmentId`), + CONSTRAINT `FK_1f10411177dbfb642f95c518f2f` FOREIGN KEY (`shipmentId`) REFERENCES `shipments` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `live_tracking` +-- + +LOCK TABLES `live_tracking` WRITE; +/*!40000 ALTER TABLE `live_tracking` DISABLE KEYS */; +INSERT INTO `live_tracking` VALUES (0x30613530353064352D646337372D3439,'2023-02-13 14:00:00',29.8997300,122.0640000),(0x34356166386138392D386530632D3439,'2023-02-13 14:00:00',33.0330400,16.1790700),(0x36376163386439632D616262302D3433,'2023-02-13 14:00:00',4.0337080,100.1649000),(0x37363630313536302D356665372D3466,'2023-02-13 14:00:00',43.2687300,-10.1082200),(0x38323862396566312D623638362D3465,'2023-02-13 14:00:00',7.5284480,70.5005930),(0x62373365366266612D653233622D3439,'2023-02-13 14:00:00',4.0842820,80.2405790),(0x63333963346162652D393361342D3433,'2023-02-13 14:00:00',21.2560070,123.6223760),(0x65383131323737652D313937392D3437,'2023-02-13 14:00:00',38.1850000,-12.0500000); +/*!40000 ALTER TABLE `live_tracking` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `shipments` +-- + +DROP TABLE IF EXISTS `shipments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `shipments` ( + `id` binary(16) NOT NULL DEFAULT (uuid_to_bin(uuid())), + `createdAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `carrierName` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, + `originPort` char(5) COLLATE utf8mb4_general_ci NOT NULL, + `destinationPort` char(5) COLLATE utf8mb4_general_ci NOT NULL, + `departureDate` datetime NOT NULL, + `arrivalDateOriginal` datetime NOT NULL, + `arrivalDateEstimate` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `shipments` +-- + +LOCK TABLES `shipments` WRITE; +/*!40000 ALTER TABLE `shipments` DISABLE KEYS */; +INSERT INTO `shipments` VALUES (0x30306432353565302D353666372D3465,'2023-01-05 06:00:00','MSC','NLAMS','CNCSX','2023-01-06 06:00:00','2023-01-27 06:00:00','2023-01-27 06:00:00'),(0x30346632663931312D653238382D3466,'2022-12-21 04:00:00','MSC','NLRTM','CNCSX','2022-12-22 04:00:00','2023-01-15 04:00:00','2023-01-15 04:00:00'),(0x30613530353064352D646337372D3439,'2023-01-14 14:00:00','MSC','NLRTM','CNNBO','2023-01-15 14:00:00','2023-02-13 14:00:00','2023-02-13 14:00:00'),(0x30613639623331612D636438322D3432,'2023-01-02 00:00:00','MSC','CNHKG','NLAMS','2023-01-03 00:00:00','2023-01-29 00:00:00','2023-01-29 00:00:00'),(0x31326139363931662D346561362D3439,'2022-12-15 11:00:00','MSC','CNCSX','NLAMS','2022-12-16 11:00:00','2023-01-02 11:00:00','2023-01-02 11:00:00'),(0x31656466613939392D353635622D3462,'2022-12-09 16:00:00','MSC','CNXMN','NLRTM','2022-12-10 16:00:00','2023-01-06 16:00:00','2023-01-06 16:00:00'),(0x32393031366466372D363066632D3437,'2022-11-28 01:00:00','MSC','NLAMS','CNNBO','2022-11-29 01:00:00','2022-12-28 01:00:00','2022-12-28 01:00:00'),(0x32396132646130322D626261372D3464,'2022-12-01 17:00:00','Evergreen','CNFZG','NLAMS','2022-12-02 17:00:00','2022-12-18 17:00:00','2022-12-18 17:00:00'),(0x32623034353230652D333735652D3438,'2023-01-04 02:00:00','MSC','CNFZG','NLRTM','2023-01-05 02:00:00','2023-01-27 02:00:00','2023-01-27 02:00:00'),(0x32626665386639632D373063622D3461,'2023-01-12 13:00:00','Evergreen','NLAMS','CNHGH','2023-01-13 13:00:00','2023-02-08 13:00:00','2023-02-08 13:00:00'),(0x32643862653936332D653837302D3464,'2023-03-17 22:00:00','Evergreen','CNSHA','NLRTM','2023-03-18 22:00:00','2023-04-04 22:00:00','2023-04-04 22:00:00'),(0x32663437653538392D343432382D3462,'2023-01-01 12:00:00','Evergreen','NLRTM','CNFOC','2023-01-02 12:00:00','2023-01-23 12:00:00','2023-01-23 12:00:00'),(0x32663631613733322D636233642D3431,'2022-11-19 05:00:00','MSC','CNFOC','NLRTM','2022-11-20 05:00:00','2022-12-09 05:00:00','2022-12-09 05:00:00'),(0x33303263313165322D333832642D3464,'2022-12-19 10:00:00','Evergreen','CNHGH','NLAMS','2022-12-20 10:00:00','2023-01-18 10:00:00','2023-01-18 10:00:00'),(0x33306530616261352D353266662D3437,'2023-02-12 20:00:00','Evergreen','CNFZG','NLRTM','2023-02-13 20:00:00','2023-03-04 20:00:00','2023-03-04 20:00:00'),(0x33353863313561342D363535662D3434,'2023-03-12 16:00:00','MSC','CNSHA','NLRTM','2023-03-13 16:00:00','2023-03-28 16:00:00','2023-03-28 16:00:00'),(0x33363635303364332D386264632D3434,'2023-02-06 07:00:00','Evergreen','NLRTM','CNHGH','2023-02-07 07:00:00','2023-03-05 07:00:00','2023-03-05 07:00:00'),(0x34356166386138392D386530632D3439,'2023-02-11 18:00:00','Evergreen','CNFZG','NLAMS','2023-02-12 18:00:00','2023-03-02 18:00:00','2023-03-02 18:00:00'),(0x34356232323564312D623135622D3465,'2023-03-28 19:00:00','MSC','NLRTM','CNFOC','2023-03-29 19:00:00','2023-04-26 19:00:00','2023-04-26 19:00:00'),(0x36376163386439632D616262302D3433,'2023-02-04 14:00:00','MSC','NLRTM','CNSHA','2023-02-05 14:00:00','2023-02-20 14:00:00','2023-02-20 14:00:00'),(0x36613934653133332D313831652D3464,'2023-02-21 10:00:00','MSC','NLRTM','CNFZG','2023-02-22 10:00:00','2023-03-19 10:00:00','2023-03-19 10:00:00'),(0x36653965333066382D393730642D3462,'2023-04-12 19:00:00','Evergreen','CNFOC','NLAMS','2023-04-13 19:00:00','2023-05-10 19:00:00','2023-05-10 19:00:00'),(0x36663562333866632D393361352D3466,'2023-04-10 10:00:00','Evergreen','NLAMS','CNCTU','2023-04-11 10:00:00','2023-05-09 10:00:00','2023-05-09 10:00:00'),(0x37363630313536302D356665372D3466,'2023-01-29 09:00:00','Evergreen','CNSHA','NLAMS','2023-01-30 09:00:00','2023-02-18 09:00:00','2023-02-18 09:00:00'),(0x37616138386138622D363339622D3464,'2023-01-26 14:00:00','MSC','NLRTM','CNSHA','2023-01-27 14:00:00','2023-02-12 14:00:00','2023-02-12 14:00:00'),(0x37633535616166332D376338372D3431,'2023-01-12 06:00:00','Evergreen','CNNBO','NLAMS','2023-01-13 06:00:00','2023-01-31 06:00:00','2023-01-31 06:00:00'),(0x38316539653863662D343562342D3430,'2023-05-13 13:00:00','Evergreen','NLAMS','CNNBO','2023-05-14 13:00:00','2023-06-01 13:00:00','2023-02-14 16:00:00'),(0x38323862396566312D623638362D3465,'2023-02-01 00:00:00','Evergreen','NLAMS','CNHKG','2023-02-02 00:00:00','2023-02-28 00:00:00','2023-02-28 00:00:00'),(0x39386463393462612D303639332D3431,'2023-04-29 01:00:00','Evergreen','CNHKG','NLAMS','2023-04-30 01:00:00','2023-05-17 01:00:00','2023-05-17 01:00:00'),(0x39396363363961632D656464382D3462,'2023-01-19 19:00:00','MSC','NLAMS','CNFZG','2023-01-20 19:00:00','2023-02-06 19:00:00','2023-02-06 19:00:00'),(0x39613561343033362D636230362D3462,'2023-03-18 16:00:00','Evergreen','CNSHA','NLRTM','2023-03-19 16:00:00','2023-04-03 16:00:00','2023-04-03 16:00:00'),(0x61306634393161612D373339652D3437,'2023-04-17 23:00:00','Evergreen','CNNBO','NLAMS','2023-04-18 23:00:00','2023-05-09 23:00:00','2023-05-09 23:00:00'),(0x61356365373438392D393436622D3430,'2023-04-05 16:00:00','MSC','CNHGH','NLAMS','2023-04-06 16:00:00','2023-05-05 16:00:00','2023-05-05 16:00:00'),(0x61386131323764662D376539642D3439,'2023-04-21 23:00:00','Evergreen','NLAMS','CNFZG','2023-04-22 23:00:00','2023-05-11 23:00:00','2023-05-11 23:00:00'),(0x62306663366364642D613663652D3434,'2023-04-05 14:00:00','Evergreen','NLRTM','CNCSX','2023-04-06 14:00:00','2023-05-01 14:00:00','2023-05-01 14:00:00'),(0x62323538393966632D333662342D3438,'2023-01-17 15:00:00','Evergreen','NLAMS','CNNBO','2023-01-18 15:00:00','2023-02-07 15:00:00','2023-02-07 15:00:00'),(0x62353035383036652D663834352D3432,'2022-11-23 06:00:00','Evergreen','NLAMS','CNHKG','2022-11-24 06:00:00','2022-12-09 06:00:00','2022-12-09 06:00:00'),(0x62373365366266612D653233622D3439,'2023-02-07 06:00:00','MSC','NLRTM','CNHKG','2023-02-08 06:00:00','2023-02-23 06:00:00','2023-02-23 06:00:00'),(0x62393437376630632D623166652D3434,'2023-03-24 11:00:00','MSC','CNXMN','NLRTM','2023-03-25 11:00:00','2023-04-22 11:00:00','2023-04-22 11:00:00'),(0x62623264653661662D643530362D3462,'2023-03-24 00:00:00','Evergreen','NLAMS','CNFOC','2023-03-25 00:00:00','2023-04-15 00:00:00','2023-04-15 00:00:00'),(0x63333963346162652D393361342D3433,'2023-01-31 05:00:00','MSC','NLRTM','CNFZG','2023-02-01 05:00:00','2023-02-19 05:00:00','2023-02-19 05:00:00'),(0x63613465323738332D616261662D3439,'2023-03-10 06:00:00','Evergreen','CNCSX','NLRTM','2023-03-11 06:00:00','2023-04-05 06:00:00','2023-04-05 06:00:00'),(0x63636533396237622D366232392D3439,'2022-11-25 08:00:00','MSC','NLAMS','CNFZG','2022-11-26 08:00:00','2022-12-13 08:00:00','2022-12-13 08:00:00'),(0x64643162326363302D393038372D3464,'2022-11-15 02:00:00','MSC','CNHGH','NLRTM','2022-11-16 02:00:00','2022-12-13 02:00:00','2022-12-13 02:00:00'),(0x64643563303131302D633164622D3433,'2023-03-06 09:00:00','Evergreen','CNXMN','NLRTM','2023-03-07 09:00:00','2023-03-30 09:00:00','2023-03-30 09:00:00'),(0x65383131323737652D313937392D3437,'2023-02-03 18:00:00','Evergreen','CNNBO','NLAMS','2023-02-04 18:00:00','2023-02-19 18:00:00','2023-02-19 18:00:00'),(0x66323732323232302D663536622D3433,'2023-01-15 06:00:00','Evergreen','CNHKG','NLRTM','2023-01-16 06:00:00','2023-02-06 06:00:00','2023-02-06 06:00:00'),(0x66343265613731392D643865352D3465,'2023-04-27 18:00:00','MSC','NLRTM','CNSHA','2023-04-28 18:00:00','2023-05-20 18:00:00','2023-05-20 18:00:00'),(0x66613733343633632D333862342D3466,'2023-05-01 11:00:00','MSC','NLRTM','CNNBO','2023-05-02 11:00:00','2023-05-27 11:00:00','2023-05-27 11:00:00'),(0x66643065346139642D383062302D3431,'2023-05-06 15:00:00','MSC','CNNBO','NLAMS','2023-05-07 15:00:00','2023-05-29 15:00:00','2023-05-29 15:00:00'); +/*!40000 ALTER TABLE `shipments` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2024-03-26 21:01:48 diff --git a/package-lock.json b/package-lock.json index 129db5a..5822c93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "UNLICENSED", "dependencies": { "@nestjs/common": "^10.3.5", + "@nestjs/config": "^3.2.1", "@nestjs/core": "^10.3.5", "@nestjs/platform-express": "^10.3.5", "@nestjs/swagger": "^7.3.0", @@ -1766,6 +1767,21 @@ } } }, + "node_modules/@nestjs/config": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-3.2.1.tgz", + "integrity": "sha512-tFZyLJKanSAu51ygQ6ZBSpx95pRcwS6qSpJDW6FFgRQzkOaOUXpL8qD8yMNoYoYxuJCxph+waiBaWKgFWxn3sw==", + "dependencies": { + "dotenv": "16.4.5", + "dotenv-expand": "10.0.0", + "lodash": "4.17.21", + "uuid": "9.0.1" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "rxjs": "^7.1.0" + } + }, "node_modules/@nestjs/core": { "version": "10.3.5", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.5.tgz", @@ -4054,6 +4070,14 @@ "url": "https://dotenvx.com" } }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "engines": { + "node": ">=12" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", diff --git a/package.json b/package.json index f4d013a..08ab022 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ }, "dependencies": { "@nestjs/common": "^10.3.5", + "@nestjs/config": "^3.2.1", "@nestjs/core": "^10.3.5", "@nestjs/platform-express": "^10.3.5", "@nestjs/swagger": "^7.3.0", @@ -67,8 +68,12 @@ "ts" ], "rootDir": ".", - "roots": ["/tests"], - "testPathIgnorePatterns": ["./database"], + "roots": [ + "/tests" + ], + "testPathIgnorePatterns": [ + "./database" + ], "testRegex": ".*\\.spec\\.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" diff --git a/track.http b/requests.http similarity index 52% rename from track.http rename to requests.http index 41a17c3..8d599eb 100644 --- a/track.http +++ b/requests.http @@ -1,5 +1,7 @@ POST http://localhost:3000/tracking +Accept: application/json Content-Type: application/json +Authorization: eG5nVnZGaWtCMFN6NjRRaWQ2TUJsUTJWaDpjeGg1R3FKRUl0UTlzSGRQdElGMGg0bFJp { "carrierName": "Evergreen", @@ -8,3 +10,9 @@ Content-Type: application/json "arrivalDateEstimate": "2023-02-14T15:00:00.000Z", "containerNumber": "EGLU866139144" } + +### + +GET http://localhost:3000/shipments +Accept: application/json +Authorization: eG5nVnZGaWtCMFN6NjRRaWQ2TUJsUTJWaDpjeGg1R3FKRUl0UTlzSGRQdElGMGg0bFJp diff --git a/src/app.controller.ts b/src/app.controller.ts deleted file mode 100644 index 7bf5dce..0000000 --- a/src/app.controller.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { - ClassSerializerInterceptor, - Controller, - Get, - UseInterceptors, -} from '@nestjs/common'; -import { AppService } from './app.service'; -import { ApiExtraModels } from '@nestjs/swagger'; -import { TrackingDto } from '@/dtos/tracking.dto'; - -@Controller() -@ApiExtraModels(TrackingDto) -@UseInterceptors(ClassSerializerInterceptor) -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - debug(): unknown { - return this.appService.debug(); - } -} diff --git a/src/app.module.ts b/src/app.module.ts index df76e41..e66865c 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,35 +1,51 @@ import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ContainerEntity } from '@/entities/container.entity'; import { LiveTrackingEntity } from '@/entities/liveTracking.entity'; import { ShipmentEntity } from '@/entities/shipment.entity'; import { TrackingModule } from './tracking/tracking.module'; import { ShipmentsModule } from './shipments/shipments.module'; +import { APP_GUARD } from '@nestjs/core'; +import { AuthGuard } from '@/guards/auth.guard'; +import { ApiKeyEntity } from '@/entities/apiKey.entity'; +import { AuthService } from '@/auth.service'; +import { ConfigModule, ConfigService } from '@nestjs/config'; @Module({ imports: [ - TypeOrmModule.forRoot({ - type: 'mysql', - host: 'localhost', - port: 13306, - username: 'root', - password: 'myfreight', - database: 'myfreight', - entities: [ContainerEntity, LiveTrackingEntity, ShipmentEntity], - synchronize: true, - logging: false, + TypeOrmModule.forRootAsync({ + imports: [ConfigModule.forRoot()], + useFactory: async (configService: ConfigService) => { + return { + type: 'mysql', + host: configService.get('DB_HOST'), + port: Number(configService.get('DB_PORT')), + username: configService.get('DB_USER'), + password: configService.get('DB_PASS'), + database: configService.get('DB_DABA'), + entities: [ + ContainerEntity, + LiveTrackingEntity, + ShipmentEntity, + ApiKeyEntity, + ], + synchronize: true, + logging: false, + }; + }, + inject: [ConfigService], }), - TypeOrmModule.forFeature([ - ContainerEntity, - LiveTrackingEntity, - ShipmentEntity, - ]), + TypeOrmModule.forFeature([ApiKeyEntity]), TrackingModule, ShipmentsModule, ], - controllers: [AppController], - providers: [AppService], + controllers: [], + providers: [ + AuthService, + { + provide: APP_GUARD, + useClass: AuthGuard, + }, + ], }) export class AppModule {} diff --git a/src/app.service.ts b/src/app.service.ts deleted file mode 100644 index 2ec496c..0000000 --- a/src/app.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { ContainerEntity } from '@/entities/container.entity'; -import { Repository } from 'typeorm'; -import { InjectRepository } from '@nestjs/typeorm'; - -@Injectable() -export class AppService { - constructor( - @InjectRepository(ContainerEntity) - private readonly containerRepository: Repository, - ) {} - async debug(): Promise { - return this.containerRepository.find({ - take: 5, - }); - - // return 'Hello World!'; - } -} diff --git a/src/auth.service.ts b/src/auth.service.ts new file mode 100644 index 0000000..6416f40 --- /dev/null +++ b/src/auth.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { ApiKeyEntity } from '@/entities/apiKey.entity'; +import * as crypto from 'crypto'; + +@Injectable() +export class AuthService { + constructor( + @InjectRepository(ApiKeyEntity) + private readonly apiKeyRepository: Repository, + ) {} + + async isAllowed(apiKey: string, apiSecret: string): Promise { + const apiKeyEntity = await this.apiKeyRepository.findOneBy({ + apiKey, + }); + + if (!apiKeyEntity || !apiKeyEntity.enabled) { + return false; + } + + const hmac = crypto.createHmac('sha256', apiSecret); + const digest = hmac.update(apiKey).digest('hex'); + + return digest === apiKeyEntity.digest; + } +} diff --git a/src/entities/apiKey.entity.ts b/src/entities/apiKey.entity.ts new file mode 100644 index 0000000..5cd6b07 --- /dev/null +++ b/src/entities/apiKey.entity.ts @@ -0,0 +1,23 @@ +import { Column, Entity, PrimaryColumn } from 'typeorm'; + +@Entity({ + name: 'apiKeys', +}) +export class ApiKeyEntity { + @PrimaryColumn({ + type: 'char', + length: 25, + }) + apiKey!: string; + + @Column({ + type: 'char', + length: 64, + }) + digest!: string; + + @Column({ + type: 'boolean', + }) + enabled!: boolean; +} diff --git a/src/guards/auth.guard.ts b/src/guards/auth.guard.ts new file mode 100644 index 0000000..eb412f3 --- /dev/null +++ b/src/guards/auth.guard.ts @@ -0,0 +1,47 @@ +import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; +import { Request } from 'express'; +import { AuthService } from '@/auth.service'; + +@Injectable() +export class AuthGuard implements CanActivate { + constructor(private readonly authService: AuthService) {} + async canActivate(context: ExecutionContext): Promise { + const request = context.switchToHttp().getRequest(); + const apiCredentials = this.extractCredentialsFromRequestApiKey(request); + + if (!apiCredentials) { + return false; + } + + return this.authService.isAllowed( + apiCredentials.key, + apiCredentials.secret, + ); + } + + private extractCredentialsFromRequestApiKey(request: Request): + | { + key: string; + secret: string; + } + | false { + const authorization = request.headers.authorization; + + if (!authorization) { + return false; + } + + const [key, secret] = Buffer.from(authorization, 'base64') + .toString('utf8') + .split(':', 2); + + if (!key || !secret) { + return false; + } + + return { + key, + secret, + }; + } +} diff --git a/src/shipments/shipments.controller.spec.ts b/src/shipments/shipments.controller.spec.ts deleted file mode 100644 index f49fad0..0000000 --- a/src/shipments/shipments.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ShipmentsController } from './shipments.controller'; - -describe('ShipmentsController', () => { - let controller: ShipmentsController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [ShipmentsController], - }).compile(); - - controller = module.get(ShipmentsController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); - - it('should', () => { - expect(true).toBe(true); - }); -}); diff --git a/src/shipments/shipments.controller.ts b/src/shipments/shipments.controller.ts index 1a979c7..c523b30 100644 --- a/src/shipments/shipments.controller.ts +++ b/src/shipments/shipments.controller.ts @@ -21,7 +21,9 @@ export class ShipmentsController { }, }, }) - getShipments() { - return this.shipmentsService.getAll(); + async getShipments() { + return { + data: await this.shipmentsService.getAll(), + }; } } diff --git a/tests/shipments/shipments.controller.spec.ts b/tests/shipments/shipments.controller.spec.ts new file mode 100644 index 0000000..2d8cd92 --- /dev/null +++ b/tests/shipments/shipments.controller.spec.ts @@ -0,0 +1,36 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ShipmentsController } from '@/shipments/shipments.controller'; +import { ShipmentsService } from '@/shipments/shipments.service'; + +describe('ShipmentsController', () => { + let controller: ShipmentsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [ShipmentsController], + }) + .useMocker((token) => { + if (token === ShipmentsService) { + return { + getAll: jest.fn().mockResolvedValue([]), + }; + } + }) + + .compile(); + + controller = module.get(ShipmentsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); + + it('should have a method getShipments', () => { + expect(controller.getShipments).toBeDefined(); + }); + + it('should return an object with message: ok', async () => { + await expect(controller.getShipments()).resolves.toEqual({ data: [] }); + }); +}); diff --git a/src/shipments/shipments.service.spec.ts b/tests/shipments/shipments.service.spec.ts similarity index 86% rename from src/shipments/shipments.service.spec.ts rename to tests/shipments/shipments.service.spec.ts index 5db7f2f..8492c4d 100644 --- a/src/shipments/shipments.service.spec.ts +++ b/tests/shipments/shipments.service.spec.ts @@ -1,5 +1,5 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { ShipmentsService } from './shipments.service'; +import { ShipmentsService } from '@/shipments/shipments.service'; describe('ShipmentsService', () => { let service: ShipmentsService;