signature: use PDFSignatureZoneParser in vue app signature

This commit is contained in:
nobohan 2024-07-04 15:17:04 +02:00
parent 5b7e3f0336
commit c428e6665f
4 changed files with 46 additions and 75 deletions

View File

@ -26,6 +26,8 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use Chill\DocStoreBundle\Service\Signature\PDFSignatureZoneParser;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
/**
* Class DocumentPersonController.
@ -40,6 +42,8 @@ class DocumentPersonController extends AbstractController
protected TranslatorInterface $translator,
protected EventDispatcherInterface $eventDispatcher,
protected AuthorizationHelper $authorizationHelper,
protected PDFSignatureZoneParser $PDFSignatureZoneParser,
protected StoredObjectManagerInterface $storedObjectManagerInterface,
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry
) {}
@ -211,9 +215,22 @@ class DocumentPersonController extends AbstractController
]);
$this->eventDispatcher->dispatch($event, PrivacyEvent::PERSON_PRIVACY_EVENT);
$storedObject = $document->getObject();
$content = $this->storedObjectManagerInterface->read($storedObject);
$zones = $this->PDFSignatureZoneParser->findSignatureZones($content);
$signature = [];
$signature['id'] = 1;
$signature['storedObject'] = [ //TEMP
'filename' => $storedObject->getFilename(),
'iv'=> $storedObject->getIv(),
'keyInfos' => $storedObject->getKeyInfos()
];
$signature['zones'] = $zones;
return $this->render(
'@ChillDocStore/PersonDocument/signature.html.twig',
['document' => $document, 'person' => $person]
['document' => $document, 'person' => $person, 'signature' => $signature]
);
}
}

View File

@ -26,11 +26,11 @@ export interface StoredObject {
}
export interface StoredObjectCreated {
status: "stored_object_created",
filename: string,
iv: Uint8Array,
keyInfos: object,
type: string,
status: "stored_object_created",
filename: string,
iv: Uint8Array,
keyInfos: object,
type: string,
}
export interface StoredObjectStatusChange {
@ -51,21 +51,24 @@ export type WopiEditButtonExecutableBeforeLeaveFunction = {
* Object containing information for performering a POST request to a swift object store
*/
export interface PostStoreObjectSignature {
method: "POST",
max_file_size: number,
max_file_count: 1,
expires: number,
submit_delay: 180,
redirect: string,
prefix: string,
url: string,
signature: string,
method: "POST",
max_file_size: number,
max_file_count: 1,
expires: number,
submit_delay: 180,
redirect: string,
prefix: string,
url: string,
signature: string,
}
export interface PDFPage {
index: number,
width: number,
height: number,
}
export interface SignatureZone {
page: number,
pageWidth: number,
pageHeight: number,
PDFPage: PDFPage,
x: number,
y: number,
width: number,

View File

@ -179,8 +179,8 @@ const hit_signature = (
canvasWidth: number,
canvasHeight: number
) => {
const scaleXToCanvas = (x: number) => (x * canvasWidth) / zone.pageWidth;
const scaleYToCanvas = (y: number) => (y * canvasHeight) / zone.pageHeight;
const scaleXToCanvas = (x: number) => (x * canvasWidth) / zone.PDFPage.width;
const scaleYToCanvas = (y: number) => (y * canvasHeight) / zone.PDFPage.height;
return (
scaleXToCanvas(zone.x) < xy[0] &&
xy[0] < scaleXToCanvas(zone.x + zone.width) &&
@ -191,7 +191,7 @@ const hit_signature = (
const canvas_click = (e: PointerEvent, canvas: HTMLCanvasElement) =>
signature.zones
.filter((z) => z.page === page.value)
.filter((z) => z.PDFPage.index + 1 === page.value)
.map((z) => {
if (
hit_signature(z, [e.offsetX, e.offsetY], canvas.width, canvas.height)
@ -217,7 +217,7 @@ const turn_page = async (upOrDown: number) => {
const turn_signature = async (upOrDown: number) => {
let currentZone = signature.zones[zone.value];
if (currentZone) {
page.value = currentZone.page;
page.value = currentZone.PDFPage.index + 1;
await set_page(page.value);
setTimeout(() => add_zones(page.value), 200);
}
@ -236,9 +236,9 @@ const draw_zone = (
selected = false
) => {
const scaleXToCanvas = (x: number) =>
Math.round((x * canvasWidth) / zone.pageWidth);
Math.round((x * canvasWidth) / zone.PDFPage.width);
const scaleYToCanvas = (y: number) =>
Math.round((y * canvasHeight) / zone.pageHeight);
Math.round((y * canvasHeight) / zone.PDFPage.height);
ctx.strokeStyle = selected ? "orange " : "yellow";
ctx.lineWidth = 10;
ctx.lineJoin = "bevel";
@ -266,7 +266,7 @@ const add_zones = (page: number) => {
const ctx = canvas.getContext("2d");
if (ctx) {
signature.zones
.filter((z) => z.page === page)
.filter((z) => z.PDFPage.index + 1 === page)
.map((z) => draw_zone(z, ctx, canvas.width, canvas.height));
}
};

View File

@ -18,56 +18,7 @@
{% block js %}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
<script type="text/javascript">
const signature = {
id: 1,
// // storedObject: {
// // filename: "gj72nCYsiuysZwZMTMVv5mhqmJdA",
// // keyInfos: {
// // alg: "A256CBC",
// // ext: true,
// // k: "WwEuXQqv5sJFzAM6P5q7Ecvbl2MiA9mE_MTQ1fAhVsY",
// // key_ops: ["encrypt", "decrypt"],
// // kty: "oct",
// // },
// // iv: [
// // 50, 124, 210, 52, 177, 145, 165, 156, 90, 186, 155, 252, 241, 54, 194, 79,
// // ],
// // },
storedObject: {
filename: "U2HmWk5MGkUW1vHRA5sMEMkW9fyf",
keyInfos: {
alg: "A256CBC",
ext: true,
k: "3GmJ8UBck3WhpmdoQy7cGQho0J9k9Rxhn23UIhqvpVY",
key_ops: ["encrypt", "decrypt"],
kty: "oct",
},
iv: [
254, 171, 69, 203, 89, 3, 202, 29, 187, 200, 19, 146, 201, 253, 79, 169,
],
},
zones: [
{
page: 1,
pageWidth: 210,
pageHeight: 297,
x: 21, //from top-left corner
y: 50,
width: 80,
height: 50,
},
{
page: 3,
pageWidth: 210,
pageHeight: 297,
x: 60, //from top-left corner
y: 20,
width: 80,
height: 50,
},
],
};
window.signature = signature;
window.signature = {{ signature|json_encode|raw }};
</script>
{{ encore_entry_script_tags('vue_document_signature') }}
{% endblock %}