diff --git a/.gitignore b/.gitignore index cc8aaaa..495e67b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ env.php scratch.* scratch/ +vendor/ # Logs logs *.log diff --git a/client/.gitignore b/client/.gitignore index 0f927a7..40de3de 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -22,6 +22,8 @@ log.txt /www /platforms /plugins +/android +/ios # Compiled output /dist diff --git a/client/package-lock.json b/client/package-lock.json index 9dcdf1a..32c5875 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -24,6 +24,7 @@ "@capacitor/status-bar": "5.0.2", "@ionic/angular": "^7.0.0", "ionicons": "^7.0.0", + "jwt-decode": "^3.1.2", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.13.0" @@ -10156,6 +10157,11 @@ "node >= 0.2.0" ] }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "node_modules/karma": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", diff --git a/client/package.json b/client/package.json index f57ad77..c165d05 100644 --- a/client/package.json +++ b/client/package.json @@ -29,6 +29,7 @@ "@capacitor/status-bar": "5.0.2", "@ionic/angular": "^7.0.0", "ionicons": "^7.0.0", + "jwt-decode": "^3.1.2", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.13.0" diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index 9093622..f131627 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts @@ -7,11 +7,17 @@ import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; -import { HttpClientModule } from '@angular/common/http'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; + +import { JWTInterceptor } from './jwtinterceptor.interceptor'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, HttpClientModule], - providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], + providers: [ + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + { provide: HTTP_INTERCEPTORS, useClass: JWTInterceptor, multi: true }, + + ], bootstrap: [AppComponent], }) export class AppModule { } diff --git a/client/src/app/jwtinterceptor.interceptor.spec.ts b/client/src/app/jwtinterceptor.interceptor.spec.ts new file mode 100644 index 0000000..202cd15 --- /dev/null +++ b/client/src/app/jwtinterceptor.interceptor.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { JWTInterceptorInterceptor } from './jwtinterceptor.interceptor'; + +describe('JWTInterceptorInterceptor', () => { + beforeEach(() => TestBed.configureTestingModule({ + providers: [ + JWTInterceptorInterceptor + ] + })); + + it('should be created', () => { + const interceptor: JWTInterceptorInterceptor = TestBed.inject(JWTInterceptorInterceptor); + expect(interceptor).toBeTruthy(); + }); +}); diff --git a/client/src/app/jwtinterceptor.interceptor.ts b/client/src/app/jwtinterceptor.interceptor.ts new file mode 100644 index 0000000..1905d26 --- /dev/null +++ b/client/src/app/jwtinterceptor.interceptor.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +@Injectable() +export class JWTInterceptor implements HttpInterceptor { + intercept(req: HttpRequest, next: HttpHandler): Observable> { + const jwt = sessionStorage.getItem('JWT'); // Assuming JWT is stored in sessionStorage + + if (jwt) { + const cloned = req.clone({ + setHeaders: { + Authorization: `Bearer ${jwt}`, + }, + }); + + console.log(cloned); + + return next.handle(cloned); + } else { + return next.handle(req); + } + } +} diff --git a/client/src/app/services/user-data.service.ts b/client/src/app/services/user-data.service.ts index b470452..1f88e00 100644 --- a/client/src/app/services/user-data.service.ts +++ b/client/src/app/services/user-data.service.ts @@ -9,8 +9,9 @@ import { Router } from '@angular/router'; providedIn: 'root' }) export class UserDataService { - private url = 'https://www.brain-lift.org/brain-lift/server/api/user/'; + // private url = 'https://www.brain-lift.org/brain-lift/server/api/user/'; + private url = 'http://localhost/brain-lift/server/api/user/'; constructor(private http: HttpClient, private router: Router) { } @@ -105,6 +106,14 @@ export class UserDataService { } + authenticate(username: string, password: string) { + const loginURL = `${this.url}auth/`; + + this.http.post<{ token: string }>(loginURL, { username, password }) + .subscribe(res => { + localStorage.setItem('JWT', res.token); + }); + } @@ -121,6 +130,7 @@ export class UserDataService { console.log() + } @@ -129,4 +139,12 @@ export class UserDataService { const getSessionDataURL = `${this.url}/get_session_data.php`; return this.http.get(getSessionDataURL); } + + getJWT() { + const url = 'http://localhost/brain-lift/server/api/user/'; + const jwtURL = `${url}auth/jwt-encode.php`; + return this.http.get(jwtURL) + } + + } diff --git a/client/src/app/test/test.page.html b/client/src/app/test/test.page.html index cec2d67..cbaf921 100644 --- a/client/src/app/test/test.page.html +++ b/client/src/app/test/test.page.html @@ -53,14 +53,18 @@ Start Session Data - + Store Session Data - + Get Session Data + JWT Data + + Get JWT + {{jwt}} diff --git a/client/src/app/test/test.page.ts b/client/src/app/test/test.page.ts index 7717721..9d24bf5 100644 --- a/client/src/app/test/test.page.ts +++ b/client/src/app/test/test.page.ts @@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core'; import { TaskDataService } from '../services/task-data.service'; import { AnswerDataService } from '../services/answer-data.service'; import { UserDataService } from '../services/user-data.service'; +import jwt_decode, { JwtPayload } from 'jwt-decode' +import jwtDecode from 'jwt-decode'; @Component({ selector: 'app-test', @@ -207,17 +209,33 @@ export class TestPage implements OnInit { }); } - storeData() { + storeSessionData() { this.userDataService.storeSessionData(); } - getData() { + getSessionData() { this.userDataService.getSessionData().subscribe((data) => { console.log(data); }); } + jwt: any; + getAndDecodeJWT() { + this.userDataService.getJWT().subscribe((data) => { + this.jwt = data; + const token: string = data.toString(); + sessionStorage.setItem('JWT', JSON.stringify(data)); + + const decoded = jwtDecode(token); // Returns with the JwtPayload type + this.jwt = JSON.stringify(decoded); + + + + }) + } + + diff --git a/server/api/task/new/index.php b/server/api/task/new/index.php new file mode 100644 index 0000000..5ea6b0c --- /dev/null +++ b/server/api/task/new/index.php @@ -0,0 +1,65 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +} catch (PDOException $e) { + // If connection fails, stop the script and show an error message + die("Database connection failed: " . $e->getMessage()); +} + +// API endpoint for inserting data into a table +// Check if request method is POST + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + + // Sanitize input data + + sanitizeRequestStrings(); + $requestData = $_REQUEST; + // Check if required data is provided + if (isset($requestData['taskName']) && isset($requestData['taskType']) && isset($requestData['taskTime']) && isset($requestData['userID'])) { + + // Insert the data into the table + // Prepare and bind parameters for an insert query + + $query = "INSERT INTO $table (taskName, taskType, taskTime, userID) VALUES (:value1, :value2, :value3, :value4)"; + $stmt = $db->prepare($query); + $stmt->bindParam(':value1', $requestData['taskName']); + $stmt->bindParam(':value2', $requestData['taskType']); + $stmt->bindParam(':value3', $requestData['taskTime']); + $stmt->bindParam(':value4', $requestData['userID']); + + $stmt->execute(); + + // Set headers to return a JSON response + header('Content-Type: application/json'); + header('Access-Control-Allow-Origin: *'); // Allow requests from any origin + // Return success response + echo json_encode(array('message' => 'Data inserted successfully')); + } else { + // Return error message if required data is not provided + header('HTTP/1.1 400 Bad Request'); + header('Access-Control-Allow-Origin: *'); // Allow requests from any origin + echo json_encode(array('message' => 'Required data not provided')); + } +} diff --git a/server/api/user/auth/jwt-decode.php b/server/api/user/auth/jwt-decode.php new file mode 100644 index 0000000..efbab57 --- /dev/null +++ b/server/api/user/auth/jwt-decode.php @@ -0,0 +1,155 @@ +json_encode($e); +// header('Content-Type: application/json'); +// header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +// echo json_encode($error); + +// } + +// header('Content-Type: application/json'); +// header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +// echo json_encode($decoded); + + +// if (verifyJWT($token)) { +// $decoded = JWT::decode($token, new Key($key, 'HS256')); +// // Return the data as JSON response +// header('Content-Type: application/json'); +// header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +// echo json_encode($decoded); +// } else { +// return "Error: JWT was unable to be verified!"; +// } + + +// function verifyJWT($token) +// { +// // require('./env.php'); + +// $secret = 'lHfwaotDAiAgx23oL6ruqo2SMKq1wkODkwmT1CgckAG2'; +// $issuedAt = new DateTimeImmutable(); +// $expire = $issuedAt->modify('+6 minutes')->getTimestamp(); // Add 60 seconds +// $serverName = "https://www.brain-lift.org"; + + +// try { +// $decoded = JWT::decode($token, $secret, array('HS256')); + +// header('Content-Type: application/json'); +// header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +// echo json_encode($decoded); + +// // If the token is invalid (for example, the signature didn't match) +// // then decode will throw an exception, and we won't get this far. +// $now = new DateTimeImmutable(); + +// // Verify that the issuer (iss claim) is correct +// if ($decoded->iss !== $serverName) { + +// throw new UnexpectedValueException('Issuer claim invalid'); +// } + +// // Verify that the token is not being used before it's been issued +// if ($decoded->iat > $now->getTimestamp()) { +// throw new UnexpectedValueException('Issued At claim (iat) in the future'); +// } + +// // Verify the token is not expired +// if ($decoded->exp < $now->getTimestamp()) { +// throw new UnexpectedValueException('Token has expired'); +// } + +// // If we got this far, then the token is valid. +// return true; +// } catch (Exception $e) { +// // If the decode throws an exception, then the token was invalid and we should just let the +// // exception bubble up. +// throw $e; +// } +// } + +require_once('../../../vendor/autoload.php'); + +use Firebase\JWT\JWT; +use Firebase\JWT\Key; + + + +header('Content-Type: application/json'); +header('Access-Control-Allow-Origin: *'); // Allow requests from any origin + +if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { + header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); + header('Access-Control-Allow-Headers: Content-Type'); + exit(0); +} + +$token = $_REQUEST["token"]; +$secret = 'lHfwaotDAiAgx23oL6ruqo2SMKq1wkODkwmT1CgckAG2'; +$serverName = "https://www.brain-lift.org"; + +// try { +JWT::$leeway = 60; // $leeway in seconds + +header('Content-Type: application/json'); +header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +echo json_encode($token); + + +// $decoded = JWT::decode($jwt, new Key($key, 'HS256')); +$decoded = JWT::decode($jwt, $secret, ['HS256']); + +// list($headersB64, $payloadB64, $sig) = explode('.', $jwt); +// $decoded = json_decode(base64_decode($headersB64), true); + +header('Content-Type: application/json'); +header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +echo json_encode($serverName); + +// Verifications +$now = new DateTimeImmutable(); + +if ($decoded->iss !== $serverName) { + throw new UnexpectedValueException('Issuer claim invalid'); +} + +if ($decoded->iat > $now->getTimestamp()) { + throw new UnexpectedValueException('Issued At claim (iat) in the future'); +} + +if ($decoded->exp < $now->getTimestamp()) { + throw new UnexpectedValueException('Token has expired'); +} + +echo json_encode($decoded); +// } catch (Exception $e) { +// http_response_code(500); +// echo json_encode(['error' => $e->getMessage()]); +// exit(0); +// } diff --git a/server/api/user/auth/jwt-encode.php b/server/api/user/auth/jwt-encode.php new file mode 100644 index 0000000..1551377 --- /dev/null +++ b/server/api/user/auth/jwt-encode.php @@ -0,0 +1,121 @@ +modify('+6 minutes')->getTimestamp(); // Add 60 seconds +$serverName = "https://www.brain-lift.org"; + + +$data = [ + 'iat' => $issuedAt->getTimestamp(), // Issued at: time when the token was generated + 'iss' => $serverName, // Issuer + 'nbf' => $issuedAt->getTimestamp(), // Not before + 'exp' => $expire, // Expire + 'email' => $email, // email + 'sessionID' => $sessionID +]; + +// Encode the array to a JWT string. +$jwt = JWT::encode( + $data, + $secret, + 'HS256' +); + +// Return the data as JSON response +header('Content-Type: application/json'); +header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +echo json_encode($jwt); + + + +// // Check if request method is OPTIONS +// if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { +// // Respond to preflight request +// header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +// header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); // Allow these methods +// header('Access-Control-Allow-Headers: Content-Type'); // Allow this header +// header('Content-Type: application/json'); +// exit(0); // No further processing if OPTIONS request +// } + +// use Firebase\JWT\JWT; + +// require_once('../../../vendor/autoload.php'); +// // Retrieved from filtered POST data + +// $email = 'test@email.com'; +// $sessionID = 'phpsessionid'; + +// $secret = 'lHfwaotDAiAgx23oL6ruqo2SMKq1wkODkwmT1CgckAG2'; + +// $data = [ +// 'iat' => $issuedAt->getTimestamp(), // Issued at: time when the token was generated +// 'iss' => $serverName, // Issuer +// 'nbf' => $issuedAt->getTimestamp(), // Not before +// 'exp' => $expire, // Expire +// 'email' => $email, // email +// 'sessionID' => $sessionID +// ]; + +// // Encode the array to a JWT string. +// $jwt = JWT::encode( +// $data, +// $secret, +// 'HS256' +// ); + +// // Return the data as JSON response +// header('Content-Type: application/json'); +// header('Access-Control-Allow-Origin: *'); // Allow requests from any origin +// echo json_encode($jwt); + + + + + + +// $key = 'example_key'; +// $payload = [ +// 'iss' => 'localhost', +// 'aud' => 'http://example.com', +// 'iat' => 1356999524, +// 'nbf' => 1357000000 +// ]; + +// $headers = [ +// 'Content-Type' => 'application/json', +// 'Access-Control-Allow-Origin' => '*' +// ]; + +// // Encode headers in the JWT string +// $jwt = JWT::encode($payload, $key, 'HS256', null, $headers); + +// // Decode headers from the JWT string WITHOUT validation +// // **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified. +// // These headers could be any value sent by an attacker. +// list($headersB64, $payloadB64, $sig) = explode('.', $jwt); +// $decoded = json_decode(base64_decode($headersB64), true); + +// print_r($decoded); + +// $data; +// $data["jwt"] = $jwt; +// $data["decoded"] = $decoded; diff --git a/server/api/user/auth/jwt.php b/server/api/user/auth/jwt.php new file mode 100644 index 0000000..e9983a8 --- /dev/null +++ b/server/api/user/auth/jwt.php @@ -0,0 +1,90 @@ + $issuedAt->getTimestamp(), // Issued at: time when the token was generated + 'iss' => $serverName, // Issuer + 'nbf' => $issuedAt->getTimestamp(), // Not before + 'exp' => $expire, // Expire + 'email' => $email, // email + 'sessionID' => $sessionID + ]; + + // Encode the array to a JWT string. + $jwt = JWT::encode( + $data, + $secret, + 'HS512' + ); + + // Return the data as JSON response + header('Content-Type: application/json'); + header('Access-Control-Allow-Origin: *'); // Allow requests from any origin + return json_encode($jwt); +} + +function decodeJWT($token) +{ + require('./env.php'); + + if (verifyJWT($token)) { + $decoded = JWT::decode($token, new Key($key, 'HS512')); + return $decoded; + } else { + return "Error: JWT was unable to be verified!"; + } +} + +function verifyJWT($token) +{ + require('./env.php'); + + try { + $decoded = JWT::decode($token, $secret, array('HS512')); + + // If the token is invalid (for example, the signature didn't match) + // then decode will throw an exception, and we won't get this far. + $now = new DateTimeImmutable(); + + // Verify that the issuer (iss claim) is correct + if ($decoded->iss !== $serverName) { + throw new UnexpectedValueException('Issuer claim invalid'); + } + + // Verify that the token is not being used before it's been issued + if ($decoded->iat > $now->getTimestamp()) { + throw new UnexpectedValueException('Issued At claim (iat) in the future'); + } + + // Verify the token is not expired + if ($decoded->exp < $now->getTimestamp()) { + throw new UnexpectedValueException('Token has expired'); + } + + // If we got this far, then the token is valid. + return true; + } catch (Exception $e) { + // If the decode throws an exception, then the token was invalid and we should just let the + // exception bubble up. + throw $e; + } +} diff --git a/server/api/user/auth/test.php b/server/api/user/auth/test.php new file mode 100644 index 0000000..ad23257 --- /dev/null +++ b/server/api/user/auth/test.php @@ -0,0 +1,73 @@ +modify('+6 minutes')->getTimestamp(); // Add 60 seconds +$serverName = "https://www.brain-lift.org"; + + +$data = [ + 'iat' => $issuedAt->getTimestamp(), // Issued at: time when the token was generated + 'iss' => $serverName, // Issuer + 'nbf' => $issuedAt->getTimestamp(), // Not before + 'exp' => $expire, // Expire + 'email' => $email, // email + 'sessionID' => $sessionID +]; + +$headers = [ + 'x-forwarded-for' => 'www.google.com' +]; + + +try { + // $jwt = ""; + // $jwt = JWT::decode($data, $secret, 'HS256'); + list($payloadB64, $sig) = explode('.', $jwt); + $decoded = json_decode(base64_decode($payloadB64), true); + + // $decoded = JWT::decode($jwt, new Key($key, 'HS256')); + + header('Content-Type: application/json'); + header('Access-Control-Allow-Origin: *'); // Allow requests from any origin + echo json_encode($decoded); +} catch (Exception $e) { + header('Content-Type: application/json'); + header('Access-Control-Allow-Origin: *'); // Allow requests from any origin + echo json_encode($e); +} +// Encode headers in the JWT string + +// Decode headers from the JWT string WITHOUT validation +// **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified. +// These headers could be any value sent by an attacker. +// list($headersB64, $payloadB64, $sig) = explode('.', $jwt); +// $decoded = json_decode(base64_decode($headersB64), true); + +// print_r($decoded); + +// header('Content-Type: application/json'); +// header('Access-Control-Allow-Origin: *'); // Allow requests from any origin + +// echo json_encode(array( +// "jwt" => $jwt, +// "decoded" => $decoded +// )); diff --git a/server/api/validate-json.php b/server/api/validate-json.php new file mode 100644 index 0000000..c402fa0 --- /dev/null +++ b/server/api/validate-json.php @@ -0,0 +1,41 @@ + + + $secret_key = 'YOUR_SECRET_KEY'; + + try { + $decoded = JWT::decode($jwt, $secret_key, array('HS256')); + + // If the JWT is valid, you'll have the token's payload in the $decoded variable + + // Now you can proceed with the request, user is authenticated + + } catch (\Firebase\JWT\ExpiredException $e) { + // Token has expired + http_response_code(401); + echo json_encode(["error" => $e->getMessage()]); + exit(0); + } catch (\Firebase\JWT\SignatureInvalidException $e) { + // Token is invalid + http_response_code(401); + echo json_encode(["error" => $e->getMessage()]); + exit(0); + } catch (\Exception $e) { + // Other errors + http_response_code(400); + echo json_encode(["error" => $e->getMessage()]); + exit(0); + } +} else { + // No token provided + http_response_code(401); + echo json_encode(["message" => "Not authorized"]); + exit(0); +} diff --git a/server/composer.json b/server/composer.json new file mode 100644 index 0000000..89cea0b --- /dev/null +++ b/server/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "firebase/php-jwt": "^6.5" + } +} diff --git a/server/composer.lock b/server/composer.lock new file mode 100644 index 0000000..a27f626 --- /dev/null +++ b/server/composer.lock @@ -0,0 +1,82 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "5e6a09b9f941e866184c0f2dd903ca78", + "packages": [ + { + "name": "firebase/php-jwt", + "version": "v6.5.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/e94e7353302b0c11ec3cfff7180cd0b1743975d2", + "reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2", + "shasum": "" + }, + "require": { + "php": "^7.4||^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.5.0" + }, + "time": "2023-05-12T15:47:07+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/server/todo.md b/server/todo.md new file mode 100644 index 0000000..64a3d67 --- /dev/null +++ b/server/todo.md @@ -0,0 +1,13 @@ +# To Do List + +## turn all get requests to POST requests + +## send sessionID and userID from client + +## by trying JWTs, I might be able to avoid multiple POST requests by providing a method variable with the JWT. It's industry standard. + +## my own implementation might not look as good to employers. though php session id is pretty secure, it's not JWT secure + +## give it one try + +## if it fails, go back to PHPSESSID and maybe save client ip address as well? maybe base64url token too?