#include <ArduinoJson.h>
#include <RTClib.h>
#include <CustomJWT.h>
CustomJWT* jwt;
RTC_DS3231 rtc;
void InitRTC() {
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was
// compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//rtc.adjust(DateTime(2024, 7, 8, 11, 35, 0));
// This line sets the RTC with an explicit date & time, for example to
// set January 21, 2014 at 3am you would call: rtc.adjust(DateTime(2014,
// 1, 21, 3, 0, 0));
}
}
void payloadGeneration(char* &payload, TimeSpan timespan){
DateTime now = rtc.now();
DateTime future = now + timespan;
String start_payload = "{";
String end_payload = "}";
String iat = "\"iat\": " + String(now.unixtime()); // timestamp
String exp = "\"exp\": " + String(future.unixtime()); // expiration time
String iss = "\"iss\": \"BATERURGIA\""; // issuer
String jti = "\"jti\": \"123-5698-85699\"";
String final_payload_string = start_payload +
jti + ", " +
iss + ", " +
iat + ", " +
exp +
end_payload;
payload = (char*) malloc(final_payload_string.length() + 1);
if (payload != NULL) {
final_payload_string.toCharArray(payload, final_payload_string.length() + 1);
} else {
// Manejar el caso de error de asignación de memoria
Serial.println("Error: No se pudo asignar memoria para el token.");
}
Serial.printf("payload: %s\n", payload);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32-S3!");
InitRTC();
jwt = new CustomJWT("secret", 256);
jwt->allocateJWTMemory();
// PAYLOAD GENERATION
char* payload;
TimeSpan timespan = TimeSpan(0, 0, 30, 00);
payloadGeneration(payload, timespan);
// TOKEN GENERATION
jwt->encodeJWT(payload);
free(payload);
Serial.printf("Header: %s\nHeader Length: %d\n", jwt->header, jwt->headerLength);
Serial.printf("Payload: %s\nPayload Length: %d\n", jwt->payload, jwt->payloadLength);
Serial.printf("Signature: %s\nSignature Length: %d\n", jwt->signature, jwt->signatureLength);
Serial.printf("Final token: %s\n", jwt->out);
// TOKEN AND JSON
JsonDocument json_token;
String token_send;
json_token["token"] = jwt->out;
serializeJson(json_token, token_send);
Serial.printf("token_send: %s\n", token_send.c_str());
// Llega el JSON en un JsonDocument
const char* token_incoming = json_token["token"];
Serial.printf("token_incoming: %s\n", token_incoming);
char token_for_decode[strlen(token_incoming) + 1]; // se copia a un char normal
strcpy(token_for_decode, token_incoming);
int decode_state = jwt->decodeJWT(token_for_decode); // espera un char normal, de ahí la copia
Serial.printf("decode_state: %d\n", decode_state);
char payload_from_token[jwt->payloadLength + 1];
strcpy(payload_from_token, jwt->payload);
JsonDocument json_payload;
deserializeJson(json_payload, payload_from_token);
long time_iat = json_payload["iat"];
long time_exp = json_payload["exp"];
Serial.printf("time_iat: %ld\n", time_iat);
if (decode_state != 0) Serial.println("Token no válido");
else {
DateTime now = rtc.now();
Serial.printf("Time now: %s\n", now.timestamp().c_str());
Serial.printf("Time now in unix time: %ld\n", now.unixtime());
Serial.printf("Time now in seconds time: %ld\n", now.secondstime());
if (time_exp < now.unixtime()) Serial.println("Válido pero expirado");
else Serial.println("Válido y sin expirar");
}
}
void loop() {
// put your main code here, to run repeatedly:
delay(10); // this speeds up the simulation
}