korrektur
This commit is contained in:
parent
11b28ef9c3
commit
bb058306f0
7 changed files with 370 additions and 189 deletions
76
doc/KSeF/KSEF_CLIENT.md
Normal file
76
doc/KSeF/KSEF_CLIENT.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# ksef-client
|
||||
|
||||
Um die ksef-client Library nutzen zu können muss man eine relativ komplexe prozedur durchlaufen um Zugrifff darauf zu erhalen:
|
||||
|
||||
## 1. Personal Access Token (PAT) erstellen
|
||||
|
||||
Du brauchst einen GitHub-Token, damit dein Projekt das Paket aus GitHub Packages herunterladen darf.
|
||||
|
||||
So machst du das:
|
||||
|
||||
1. Klicke oben rechts auf GitHub auf dein Profil.
|
||||
2. Gehe zu Settings.
|
||||
3. Links unten: Developer settings.
|
||||
4. Dann: Personal access tokens.
|
||||
5. Dann: Tokens (classic).
|
||||
6. Klicke: Generate new token (classic).
|
||||
|
||||
**Beim Erstellen:**
|
||||
|
||||
- Vergib irgendeinen Namen (z. B. „ksef-client access“).
|
||||
- Wähle nur ein einziges Häkchen:
|
||||
|
||||
👉 read:packages
|
||||
|
||||
- Token generieren → Token kopieren! Du siehst ihn nur einmal.
|
||||
|
||||
## 2. Maven für GitHub Packages konfigurieren
|
||||
|
||||
Damit Maven die Pakete laden kann, musst du GitHub Packages in der Datei `~/.m2/settings.xml` eintragen.
|
||||
|
||||
👉 Inhalt, den du einfügen musst:
|
||||
|
||||
```xml
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
|
||||
https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
<servers>
|
||||
<server>
|
||||
<id>github-cirfmf</id>
|
||||
<username>rsoika</username>
|
||||
<password>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</password>
|
||||
</server>
|
||||
|
||||
</servers>
|
||||
</settings>
|
||||
|
||||
```
|
||||
|
||||
## 3. Repository in deiner pom.xml eintragen
|
||||
|
||||
Füge das in deine pom.xml ein:
|
||||
|
||||
```
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>github-cirfmf</id>
|
||||
<url>https://maven.pkg.github.com/CIRFMF/ksef-client-java</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
```
|
||||
|
||||
## 4. Abhängigkeit hinzufügen
|
||||
|
||||
Auch in die pom.xml:
|
||||
|
||||
```xml
|
||||
..
|
||||
<dependency>
|
||||
<groupId>pl.akmf.ksef-sdk</groupId>
|
||||
<artifactId>ksef-client</artifactId>
|
||||
<version>3.0.4</version>
|
||||
</dependency>
|
||||
...
|
||||
```
|
||||
|
|
@ -400,12 +400,18 @@
|
|||
|
||||
<!-- KSeF 2.0 Client -->
|
||||
<dependency>
|
||||
<groupId>io.alapierre.ksef-sdk</groupId>
|
||||
<groupId>pl.akmf.ksef-sdk</groupId>
|
||||
<artifactId>ksef-client</artifactId>
|
||||
<version>2.1.8</version>
|
||||
<version>3.0.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>github-cirfmf</id>
|
||||
<url>https://maven.pkg.github.com/CIRFMF/ksef-client-java</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
|
|
@ -7,7 +7,11 @@ import java.security.InvalidAlgorithmParameterException;
|
|||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
|
|
@ -18,6 +22,7 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
|
||||
import org.imixs.workflow.FileData;
|
||||
import org.imixs.workflow.ItemCollection;
|
||||
import org.imixs.workflow.engine.DocumentService;
|
||||
import org.imixs.workflow.exceptions.PluginException;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
|
@ -36,172 +41,185 @@ import jakarta.json.bind.JsonbBuilder;
|
|||
*
|
||||
*/
|
||||
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
||||
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
||||
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
||||
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
||||
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
||||
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
||||
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
||||
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
||||
@Singleton
|
||||
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
||||
public class KSeFAPIService {
|
||||
|
||||
private static Logger logger = Logger.getLogger(KSeFAPIService.class.getName());
|
||||
private static Logger logger = Logger.getLogger(KSeFAPIService.class.getName());
|
||||
|
||||
public static final String ERROR_API = "API_ERROR";
|
||||
public static final String ERROR_API = "API_ERROR";
|
||||
|
||||
@Inject
|
||||
KSeFAuthManager kseFAuthManager;
|
||||
@Inject
|
||||
KSeFAuthManager kseFAuthManager;
|
||||
|
||||
@PostConstruct
|
||||
void init() {
|
||||
@Inject
|
||||
DocumentService documentService;
|
||||
|
||||
}
|
||||
@PostConstruct
|
||||
void init() {
|
||||
|
||||
/**
|
||||
* This method uploads a KSeF Invoice document (XML).
|
||||
* The response of the upload is a 'referenceNumber' which is stored into the
|
||||
* item ksef.referenceNumber
|
||||
*
|
||||
* @param workitem - the workitem containing the invoice file
|
||||
* @param fileName - the name of the invoice file to upload
|
||||
* @return referenceNumber - the KSeF reference number for the uploaded invoice
|
||||
* @throws PluginException
|
||||
*/
|
||||
public String uploadInvoice(ItemCollection workitem, String fileName)
|
||||
throws PluginException {
|
||||
String referenceNumber = null;
|
||||
logger.info("├── Upload Invoice...");
|
||||
|
||||
// First open an interactive Session. The KSeFAuthManager automatically reuses
|
||||
// an existing session
|
||||
kseFAuthManager.openSession();
|
||||
|
||||
if (kseFAuthManager.getAccessToken() == null) {
|
||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||
"API Error - missing AccessToken!");
|
||||
}
|
||||
if (kseFAuthManager.getSessionRefNumber() == null) {
|
||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||
"API Error - missing SessionRefNumber!");
|
||||
}
|
||||
|
||||
// Get session encryption keys
|
||||
byte[] aesKeyBytes = kseFAuthManager.getSessionAesKey();
|
||||
byte[] ivBytes = kseFAuthManager.getSessionIv();
|
||||
/**
|
||||
* This method uploads an KSeF Invoice document (XML).
|
||||
* The response of the uplaod is a 'referenceNumber' which is stored into the
|
||||
* item ksef.referenceNumber
|
||||
*
|
||||
*
|
||||
* @param companyName
|
||||
* @param contactType
|
||||
* @param accessToken
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public String uploadInvoice(ItemCollection workitem, String fileName)
|
||||
throws PluginException {
|
||||
String referenceNumber = null;
|
||||
logger.info("├── Upload Invoice...");
|
||||
|
||||
if (aesKeyBytes == null || ivBytes == null) {
|
||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||
"API Error - missing session encryption keys!");
|
||||
// First open an interactive Session. The KSeFAuthManager automatically reuses
|
||||
// an existing session
|
||||
|
||||
kseFAuthManager.openSession();
|
||||
|
||||
if (kseFAuthManager.getAccessToken() == null) {
|
||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||
"API Error - missing AccessToken!");
|
||||
}
|
||||
if (kseFAuthManager.getSessionRefNumber() == null) {
|
||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||
"API Error - missing SessionRefNumber!");
|
||||
}
|
||||
|
||||
// load invoice
|
||||
FileData fileData = workitem.getFileData(fileName);
|
||||
|
||||
byte[] invoiceXml = fileData.getContent();
|
||||
|
||||
logger.info("│ ├── XML Invoice loaded - " + invoiceXml.length + " bytes");
|
||||
try {
|
||||
// ---------- 3) AES Key generieren ----------
|
||||
logger.info("│ ├── Generate AES Key...");
|
||||
SecureRandom random = new SecureRandom();
|
||||
|
||||
byte[] aesKeyBytes = new byte[32]; // 256-bit AES key
|
||||
random.nextBytes(aesKeyBytes);
|
||||
|
||||
byte[] ivBytes = new byte[16]; // 128-bit IV
|
||||
random.nextBytes(ivBytes);
|
||||
|
||||
SecretKeySpec aesKey = new SecretKeySpec(aesKeyBytes, "AES");
|
||||
IvParameterSpec iv = new IvParameterSpec(ivBytes);
|
||||
|
||||
// ---------- 4) XML per AES-256-CBC verschlüsseln ----------
|
||||
javax.crypto.Cipher aesCipher;
|
||||
|
||||
aesCipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
|
||||
aesCipher.init(javax.crypto.Cipher.ENCRYPT_MODE, aesKey, iv);
|
||||
|
||||
byte[] encryptedInvoiceXml = aesCipher.doFinal(invoiceXml);
|
||||
|
||||
// ---------- 5) AES Key per RSA verschlüsseln ----------
|
||||
PublicKey ksefPublicKey = kseFAuthManager.getSymmetricPublicKey();
|
||||
|
||||
javax.crypto.Cipher rsaCipher = javax.crypto.Cipher
|
||||
.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
|
||||
rsaCipher.init(javax.crypto.Cipher.ENCRYPT_MODE, ksefPublicKey);
|
||||
|
||||
byte[] encryptedAesKey = rsaCipher.doFinal(aesKeyBytes);
|
||||
|
||||
// ---------- 6) SHA-256 Hash des Klartext-XML berechnen ----------
|
||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
// hash origin invoice
|
||||
byte[] xmlHashBytes = sha256.digest(invoiceXml);
|
||||
String invoiceHash = Base64.getEncoder().encodeToString(xmlHashBytes);
|
||||
|
||||
// hash encrypted invoice
|
||||
xmlHashBytes = sha256.digest(encryptedInvoiceXml);
|
||||
String encryptedInvoiceHash = Base64.getEncoder().encodeToString(xmlHashBytes);
|
||||
|
||||
// ---------- 7) Request-Body bauen ----------
|
||||
// Struktur gemäß KSeF-Doku
|
||||
String jsonBody = String.format("{ " +
|
||||
"\"invoiceHash\": \"%s\", " +
|
||||
"\"invoiceSize\": \"%s\", " +
|
||||
"\"encryptedInvoiceHash\": \"%s\", " +
|
||||
"\"encryptedInvoiceSize\": \"%s\", " +
|
||||
"\"encryptedInvoiceContent\": \"%s\", " +
|
||||
"\"offlineMode\": false " +
|
||||
"}",
|
||||
invoiceHash,
|
||||
invoiceXml.length,
|
||||
encryptedInvoiceHash,
|
||||
encryptedInvoiceXml.length,
|
||||
Base64.getEncoder().encodeToString(encryptedInvoiceXml));
|
||||
|
||||
// ---------- 8) HTTP POST vorbereiten ----------
|
||||
// String uri = manager.getBaseURI() + "/sessions/online/" +
|
||||
// manager.getRefNumber() + "/invoices";
|
||||
String uri = kseFAuthManager.getBaseURI() + "/sessions/online/"
|
||||
+ kseFAuthManager.getSessionRefNumber()
|
||||
+ "/invoices";
|
||||
logger.info("│ ├── Endpoint: " + uri);
|
||||
|
||||
if (kseFAuthManager.isDebug()) {
|
||||
logger.info("Request: " + jsonBody);
|
||||
}
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(uri))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", "Bearer " + kseFAuthManager.getAccessToken())
|
||||
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
|
||||
.build();
|
||||
|
||||
// ---------- 9) Call ausführen ----------
|
||||
var response = kseFAuthManager.getHttpClient().send(request,
|
||||
java.net.http.HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
System.out.println("Upload Response:");
|
||||
System.out.println(response.statusCode());
|
||||
System.out.println(response.body());
|
||||
|
||||
try (Jsonb jsonb = JsonbBuilder.create()) {
|
||||
// Annahme: response.body() ist ein String mit JSON-Inhalt
|
||||
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
||||
referenceNumber = jsonObject.getString("referenceNumber");
|
||||
|
||||
if (kseFAuthManager.isDebug()) {
|
||||
logger.info("│ ├── referenceNumber: " + referenceNumber);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.severe("├── ⚠️ Error parsing JSON response" + e.getMessage());
|
||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||
"Error parsing JSON response: " + e.getMessage());
|
||||
|
||||
}
|
||||
|
||||
if (response.statusCode() == 202) {
|
||||
logger.info("├── ✅ Upload successful ");
|
||||
} else {
|
||||
logger.info("├── ⚠️ Upload failed! ");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | IOException | InterruptedException
|
||||
| InvalidKeyException | IllegalBlockSizeException | BadPaddingException
|
||||
| InvalidAlgorithmParameterException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// finally set the referenceNumber
|
||||
List<Object> textlist = new ArrayList<Object>();
|
||||
textlist.add(referenceNumber);
|
||||
fileData.setAttribute("ksef.referenceNumber", textlist);
|
||||
|
||||
return referenceNumber;
|
||||
}
|
||||
|
||||
// Load invoice file
|
||||
FileData fileData = workitem.getFileData(fileName);
|
||||
if (fileData == null) {
|
||||
throw new PluginException(KSeFAPIService.class.getSimpleName(), ERROR_API,
|
||||
"File not found: " + fileName);
|
||||
}
|
||||
|
||||
byte[] invoiceXml = fileData.getContent();
|
||||
logger.info("│ ├── XML Invoice loaded - " + invoiceXml.length + " bytes");
|
||||
|
||||
try {
|
||||
// ---------- 1) Use session AES key and IV ----------
|
||||
logger.info("│ ├── Using session AES Key...");
|
||||
SecretKeySpec aesKey = new SecretKeySpec(aesKeyBytes, "AES");
|
||||
IvParameterSpec iv = new IvParameterSpec(ivBytes);
|
||||
|
||||
// ---------- 2) Encrypt XML with AES-256-CBC ----------
|
||||
logger.info("│ ├── Encrypting invoice with AES...");
|
||||
javax.crypto.Cipher aesCipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
aesCipher.init(javax.crypto.Cipher.ENCRYPT_MODE, aesKey, iv);
|
||||
byte[] encryptedInvoiceXml = aesCipher.doFinal(invoiceXml);
|
||||
|
||||
// ---------- 3) Calculate SHA-256 hashes ----------
|
||||
logger.info("│ ├── Calculating hashes...");
|
||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
// Hash of original invoice
|
||||
byte[] xmlHashBytes = sha256.digest(invoiceXml);
|
||||
String invoiceHash = Base64.getEncoder().encodeToString(xmlHashBytes);
|
||||
|
||||
// Hash of encrypted invoice
|
||||
xmlHashBytes = sha256.digest(encryptedInvoiceXml);
|
||||
String encryptedInvoiceHash = Base64.getEncoder().encodeToString(xmlHashBytes);
|
||||
|
||||
// ---------- 4) Build request body ----------
|
||||
String jsonBody = String.format("{ " +
|
||||
"\"invoiceHash\": \"%s\", " +
|
||||
"\"invoiceSize\": %d, " +
|
||||
"\"encryptedInvoiceHash\": \"%s\", " +
|
||||
"\"encryptedInvoiceSize\": %d, " +
|
||||
"\"encryptedInvoiceContent\": \"%s\", " +
|
||||
"\"offlineMode\": false " +
|
||||
"}",
|
||||
invoiceHash,
|
||||
invoiceXml.length,
|
||||
encryptedInvoiceHash,
|
||||
encryptedInvoiceXml.length,
|
||||
Base64.getEncoder().encodeToString(encryptedInvoiceXml));
|
||||
|
||||
// ---------- 5) Prepare HTTP POST request ----------
|
||||
String uri = kseFAuthManager.getBaseURI() + "/sessions/online/"
|
||||
+ kseFAuthManager.getSessionRefNumber() + "/invoices";
|
||||
logger.info("│ ├── Endpoint: " + uri);
|
||||
|
||||
if (kseFAuthManager.isDebug()) {
|
||||
logger.info("│ ├── Request body: " + jsonBody);
|
||||
}
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(uri))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", "Bearer " + kseFAuthManager.getAccessToken())
|
||||
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
|
||||
.build();
|
||||
|
||||
// ---------- 6) Execute request ----------
|
||||
logger.info("│ ├── Sending request...");
|
||||
var response = kseFAuthManager.getHttpClient().send(request,
|
||||
java.net.http.HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
logger.info("│ ├── Response Code: " + response.statusCode());
|
||||
|
||||
if (kseFAuthManager.isDebug()) {
|
||||
logger.info("│ ├── Response Body: " + response.body());
|
||||
}
|
||||
|
||||
// ---------- 7) Validate response status ----------
|
||||
if (response.statusCode() != 202) {
|
||||
throw new PluginException(KSeFAPIService.class.getSimpleName(), ERROR_API,
|
||||
"Invoice upload failed: " + response.statusCode() + " - " + response.body());
|
||||
}
|
||||
|
||||
// ---------- 8) Parse response and extract reference number ----------
|
||||
try (Jsonb jsonb = JsonbBuilder.create()) {
|
||||
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
||||
referenceNumber = jsonObject.getString("referenceNumber");
|
||||
|
||||
logger.info("│ ├── Reference Number: " + referenceNumber);
|
||||
logger.info("├── ✅ Invoice upload successful");
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.severe("├── ⚠️ Error parsing JSON response: " + e.getMessage());
|
||||
throw new PluginException(KSeFAPIService.class.getSimpleName(), ERROR_API,
|
||||
"Error parsing JSON response: " + e.getMessage());
|
||||
}
|
||||
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
|
||||
| IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
|
||||
logger.severe("├── ⚠️ Encryption error: " + e.getMessage());
|
||||
throw new PluginException(KSeFAPIService.class.getSimpleName(), ERROR_API,
|
||||
"Encryption error during invoice upload: " + e.getMessage());
|
||||
} catch (IOException | InterruptedException e) {
|
||||
logger.severe("├── ⚠️ HTTP request error: " + e.getMessage());
|
||||
throw new PluginException(KSeFAPIService.class.getSimpleName(), ERROR_API,
|
||||
"HTTP error during invoice upload: " + e.getMessage());
|
||||
}
|
||||
|
||||
return referenceNumber;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,8 +185,9 @@ public class KSeFAuthManager {
|
|||
* @throws PluginException
|
||||
*/
|
||||
public void openSession() throws PluginException {
|
||||
logger.info("├── open new KSeF Session...");
|
||||
logger.info("├── open Session...");
|
||||
if (!hasValidSession()) {
|
||||
logger.info("│ ├── open new interactive KSeF Session...");
|
||||
// open new session
|
||||
this.loadPublicKeyCertificates();
|
||||
|
||||
|
|
@ -195,7 +196,7 @@ public class KSeFAuthManager {
|
|||
this.redeemToken();
|
||||
this.openInteractiveSession();
|
||||
} else {
|
||||
logger.info("├── reuse existing KSeF Session...");
|
||||
logger.info("│ ├── reuse existing KSeF Session...");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,40 +206,44 @@ public class KSeFAuthManager {
|
|||
* @return true if a valid session exists, false otherwise
|
||||
*/
|
||||
public boolean hasValidSession() {
|
||||
// Check if session reference number exists
|
||||
if (sessionRefNumber == null || sessionRefNumber.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if valid until timestamp exists
|
||||
if (sessionValidUntil == null || sessionValidUntil.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
try {
|
||||
// Parse the validUntil timestamp (ISO 8601 format with UTC)
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||
Instant validUntilInstant = Instant.from(formatter.parse(sessionValidUntil));
|
||||
// // Check if session reference number exists
|
||||
// if (sessionRefNumber == null || sessionRefNumber.isEmpty()) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// Get current time in UTC
|
||||
Instant now = Instant.now();
|
||||
// // Check if valid until timestamp exists
|
||||
// if (sessionValidUntil == null || sessionValidUntil.isEmpty()) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// Check if session is still valid
|
||||
boolean isValid = now.isBefore(validUntilInstant);
|
||||
// try {
|
||||
// // Parse the validUntil timestamp (ISO 8601 format with UTC)
|
||||
// DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||
// Instant validUntilInstant = Instant.from(formatter.parse(sessionValidUntil));
|
||||
|
||||
if (debug && isValid) {
|
||||
logger.info("├── Session is still valid until: " + sessionValidUntil);
|
||||
} else if (debug) {
|
||||
logger.info("├── Session expired at: " + sessionValidUntil);
|
||||
}
|
||||
// // Get current time in UTC
|
||||
// Instant now = Instant.now();
|
||||
|
||||
return isValid;
|
||||
// // Check if session is still valid
|
||||
// boolean isValid = now.isBefore(validUntilInstant);
|
||||
|
||||
} catch (Exception e) {
|
||||
// If parsing fails, assume session is invalid
|
||||
logger.warning("├── ⚠️ Error parsing sessionValidUntil timestamp: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
// if (debug && isValid) {
|
||||
// logger.info("├── Session is still valid until: " + sessionValidUntil);
|
||||
// } else if (debug) {
|
||||
// logger.info("├── Session expired at: " + sessionValidUntil);
|
||||
// }
|
||||
|
||||
// return isValid;
|
||||
|
||||
// } catch (Exception e) {
|
||||
// // If parsing fails, assume session is invalid
|
||||
// logger.warning("├── ⚠️ Error parsing sessionValidUntil timestamp: " +
|
||||
// e.getMessage());
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -447,7 +452,7 @@ public class KSeFAuthManager {
|
|||
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
||||
sessionRefNumber = jsonObject.getString("referenceNumber");
|
||||
sessionValidUntil = jsonObject.getString("validUntil");
|
||||
if (debug) {
|
||||
if (true) {
|
||||
logger.info("│ ├── Session ReferenceNumber = " + sessionRefNumber);
|
||||
logger.info("│ └── Session ValidUntil = " + sessionValidUntil);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.alexanderlogistics.ksef;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
|
|
@ -37,13 +38,20 @@ public class KSeFAPIServiceTest {
|
|||
manager.setKsefToken(Params.TOKEN);
|
||||
manager.setKsefNip(Params.NIP);
|
||||
manager.setKsefEndpoint("https://ksef-test.mf.gov.pl/api/v2");
|
||||
manager.setDebug(false);
|
||||
manager.setDebug(true);
|
||||
|
||||
// init() ausführen
|
||||
manager.init();
|
||||
|
||||
// Open Session
|
||||
manager.openSession();
|
||||
|
||||
// manager.loadPublicKeyCertificates();
|
||||
// manager.authChallenge();
|
||||
// manager.authKSeFToken();
|
||||
// manager.redeemToken();
|
||||
// manager.openInteractiveSession();
|
||||
|
||||
// Create API Service and inject manager
|
||||
apiService = new KSeFAPIService();
|
||||
apiService.kseFAuthManager = manager;
|
||||
|
|
@ -66,6 +74,10 @@ public class KSeFAPIServiceTest {
|
|||
assertFalse(referenceNumber.isEmpty(), "Reference number should not be empty");
|
||||
|
||||
logger.info("✅ Upload successful - Reference Number: " + referenceNumber);
|
||||
|
||||
FileData file = workitem.getFileData("example-invoice-01.xml");
|
||||
ItemCollection fileAttributes = new ItemCollection(file.getAttributes());
|
||||
assertEquals(referenceNumber, fileAttributes.getItemValueString("ksef.referenceNumber"));
|
||||
}
|
||||
|
||||
private ItemCollection createWorkitem() throws IOException {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
package com.alexanderlogistics.ksef;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import pl.akmf.ksef.sdk.api.services.DefaultCryptographyService;
|
||||
import pl.akmf.ksef.sdk.client.interfaces.KSeFClient;
|
||||
|
||||
/**
|
||||
* Dieser Test testet den offiziellen KSeF Client
|
||||
*
|
||||
* <dependency>
|
||||
* <groupId>pl.akmf.ksef-sdk</groupId>
|
||||
* <artifactId>ksef-client</artifactId>
|
||||
* <version>3.0.4</version>
|
||||
* <scope>test</scope>
|
||||
* </dependency>
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class KSeFClientTest {
|
||||
|
||||
private static Logger logger = Logger.getLogger(KSeFClientTest.class.getName());
|
||||
|
||||
private DefaultCryptographyService cryptographyService;
|
||||
private KSeFClient ksefClient;
|
||||
private String accessToken;
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
// Simply instantiate as POJOs
|
||||
// cryptographyService = new DefaultCryptographyService();
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 1) Challenge abholen
|
||||
// ------------------------------------------------------------
|
||||
// @Test
|
||||
// @Order(1)
|
||||
// @DisplayName("POST /api/v2/auth/token/redeem")
|
||||
// void testRedeemToken() throws Exception {
|
||||
|
||||
// EncryptionData encryptionData = cryptographyService.getEncryptionData();
|
||||
|
||||
// OpenOnlineSessionRequest request = new OpenOnlineSessionRequestBuilder()
|
||||
// .withFormCode(new FormCode(SystemCode.FA_3, SchemaVersion.VERSION_1_0E,
|
||||
// SessionValue.FA))
|
||||
// .withEncryptionInfo(encryptionData.encryptionInfo())
|
||||
// .build();
|
||||
|
||||
// OpenOnlineSessionResponse openOnlineSessionResponse =
|
||||
// ksefClient.openOnlineSession(request,
|
||||
// accessToken);
|
||||
// logger.info("OK");
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
</Adres>
|
||||
<DaneKontaktowe>
|
||||
<Email>Lucja17@example.net</Email>
|
||||
<Telefon>86-588-03-553</Telefon>
|
||||
<Telefon>86-588-03-5531</Telefon>
|
||||
</DaneKontaktowe>
|
||||
</Podmiot1>
|
||||
<Podmiot2>
|
||||
|
|
@ -92,7 +92,7 @@
|
|||
<FaWiersz>
|
||||
<NrWierszaFa>3</NrWierszaFa>
|
||||
<UU_ID>8647a6b5-f12a-3817-869e-010e4353686a</UU_ID>
|
||||
<P_7>Incredible Steel Salad</P_7>
|
||||
<P_7>Incredible Steel Salad blaasdff</P_7>
|
||||
<P_8A>szt.</P_8A>
|
||||
<P_8B>8</P_8B>
|
||||
<P_9A>11.13</P_9A>
|
||||
|
|
|
|||
Loading…
Reference in a new issue