Skip to content

Commit 9aa2deb

Browse files
committed
Add more example code
1 parent fbc6051 commit 9aa2deb

File tree

3 files changed

+277
-17
lines changed

3 files changed

+277
-17
lines changed

docs/tasks/read.mdx

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,6 @@ Use [`c2pa.read`](../../docs/js-sdk/api/c2pa.c2pa#methods) to read manifest data
1818
- **validationStatus**: A list of any validation errors encountered. See [Validation](../../docs/js-sdk/guides/validation) for more information.
1919

2020
```js
21-
const version = '0.17.2';
22-
const sampleImage = '<IMAGE_URL>';
23-
24-
import { createC2pa } from 'https://cdn.jsdelivr.net/npm/c2pa@${version}/+esm';
25-
26-
(async () => {
27-
// Initialize the c2pa-js SDK
28-
const c2pa = await createC2pa({
29-
wasmSrc:
30-
'https://cdn.jsdelivr.net/npm/c2pa@${version}/dist/assets/wasm/toolkit_bg.wasm',
31-
workerSrc:
32-
'https://cdn.jsdelivr.net/npm/c2pa@${version}/dist/c2pa.worker.min.js',
33-
});
34-
3521
try {
3622
// Read in image and get a manifest store
3723
const { manifestStore } = await c2pa.read(sampleImage);

docs/tasks/setup.mdx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,24 @@ import TabItem from '@theme/TabItem';
99

1010
<Tabs groupId="programming-lang">
1111

12-
{' '}
1312
<TabItem value="js" label="JavaScript" default>
14-
This is how to setup the JavaScript library.
13+
14+
```js
15+
const version = '0.24.2';
16+
const sampleImage = '<IMAGE_URL>';
17+
18+
import { createC2pa } from 'https://cdn.jsdelivr.net/npm/c2pa@${version}/+esm';
19+
20+
(async () => {
21+
// Initialize the c2pa-js SDK
22+
const c2pa = await createC2pa({
23+
wasmSrc:
24+
'https://cdn.jsdelivr.net/npm/c2pa@${version}/dist/assets/wasm/toolkit_bg.wasm',
25+
workerSrc:
26+
'https://cdn.jsdelivr.net/npm/c2pa@${version}/dist/c2pa.worker.min.js',
27+
});
28+
```
29+
1530
</TabItem>
1631
1732
<TabItem value="python" label="Python" default>
@@ -85,7 +100,14 @@ use std::{
85100
};
86101

87102
use anyhow::Result;
88-
use c2pa::{settings::load_settings_from_str, Builder, CallbackSigner, SigningAlg};
103+
use c2pa::{settings::load_settings_from_str, Builder, CallbackSigner, Reader};
104+
105+
use c2pa_crypto::raw_signature::SigningAlg;
106+
use serde_json::json;
107+
108+
const TEST_IMAGE: &[u8] = include_bytes!("../tests/fixtures/CA.jpg");
109+
const CERTS: &[u8] = include_bytes!("../tests/fixtures/certs/ed25519.pub");
110+
const PRIVATE_KEY: &[u8] = include_bytes!("../tests/fixtures/certs/ed25519.pem");
89111
```
90112
91113
</TabItem>

docs/tasks/sign.mdx

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,262 @@ import TabItem from '@theme/TabItem';
99
<Tabs groupId="programming-lang">
1010
<TabItem value="python" label="Python" default>
1111
This is how to sign a manifest using Python.
12+
13+
```python
14+
request_data = ... # This is the asset being signed
15+
content_type = ... # MIME type of the asset
16+
17+
manifest = json.dumps({
18+
"title": "image.jpg",
19+
"format": "image/jpeg",
20+
"claim_generator_info": [
21+
{
22+
"name": "Documentation example",
23+
"version": "0.0.1"
24+
}
25+
],
26+
"assertions": [
27+
{
28+
"label": "c2pa.actions",
29+
"data": {
30+
"actions": [
31+
{
32+
"action": "c2pa.edited",
33+
"softwareAgent": {
34+
"name": "C2PA Python Example",
35+
"version": "0.1.0"
36+
}
37+
}
38+
]
39+
}
40+
}
41+
]
42+
})
43+
44+
try:
45+
builder = Builder(manifest)
46+
47+
signer = create_signer(kms_sign, signing_alg,
48+
cert_chain, timestamp_url)
49+
50+
result = io.BytesIO(b"")
51+
builder.sign(signer, content_type, io.BytesIO(request_data), result)
52+
53+
return result.getvalue()
54+
except Exception as e:
55+
logging.error(e)
56+
abort(500, description=e)
57+
```
58+
1259
</TabItem>
1360

1461
<TabItem value="node" label="Node.js">
1562
This is how to sign a manifest using Node.js.
63+
64+
Use the `c2pa.sign()` method to sign an ingredient, either locally if you have a signing certificate and key available, or by using a remote signing API.
65+
66+
## Signing buffers
67+
68+
If you have an asset file's data loaded into memory, you can sign the the asset using the loaded buffer.
69+
70+
**NOTE**: Signing using a buffer is currently supported only for `image/jpeg` and `image/png` data. For all other file types, use the [file-based approach](#signing-files) .
71+
72+
```ts
73+
import { readFile } from 'node:fs/promises';
74+
import { createC2pa, createTestSigner } from 'c2pa-node';
75+
76+
// read an asset into a buffer
77+
const buffer = await readFile('to-be-signed.jpg');
78+
const asset: Asset = { buffer, mimeType: 'image/jpeg' };
79+
80+
// build a manifest to use for signing
81+
const manifest = new ManifestBuilder(
82+
{
83+
claim_generator: 'my-app/1.0.0',
84+
format: 'image/jpeg',
85+
title: 'buffer_signer.jpg',
86+
assertions: [
87+
{
88+
label: 'c2pa.actions',
89+
data: {
90+
actions: [
91+
{
92+
action: 'c2pa.created',
93+
},
94+
],
95+
},
96+
},
97+
{
98+
label: 'com.custom.my-assertion',
99+
data: {
100+
description: 'My custom test assertion',
101+
version: '1.0.0',
102+
},
103+
},
104+
],
105+
},
106+
{ vendor: 'cai' },
107+
);
108+
109+
// create a signing function
110+
async function sign(asset, manifest) {
111+
const signer = await createTestSigner();
112+
const c2pa = createC2pa({
113+
signer,
114+
});
115+
116+
const { signedAsset, signedManifest } = await c2pa.sign({
117+
asset,
118+
manifest,
119+
});
120+
}
121+
122+
// sign
123+
await sign(asset, manifest);
124+
```
125+
126+
## Signing files
127+
128+
To avoid loading the entire asset into memory (or for file types other than JPEG and PNG that don't support in-memory signing), pass in the file path to the asset file to sign it; for example:
129+
130+
```ts
131+
import { resolve } from 'node:path';
132+
import { createC2pa, createTestSigner } from 'c2pa-node';
133+
134+
// get the asset full path
135+
const asset = {
136+
path: resolve('to-be-signed.jpg'),
137+
};
138+
// define a location where to place the signed asset
139+
const outputPath = resolve('signed.jpg');
140+
141+
// create a signing function
142+
async function sign(asset, manifest) {
143+
const signer = await createTestSigner();
144+
const c2pa = createC2pa({
145+
signer,
146+
});
147+
148+
const { signedAsset, signedManifest } = await c2pa.sign({
149+
manifest,
150+
asset,
151+
options: {
152+
outputPath,
153+
},
154+
});
155+
}
156+
157+
// build a manifest to use for signing
158+
const manifest = new ManifestBuilder(
159+
{
160+
claim_generator: 'my-app/1.0.0',
161+
format: 'image/jpeg',
162+
title: 'buffer_signer.jpg',
163+
assertions: [
164+
{
165+
label: 'c2pa.actions',
166+
data: {
167+
actions: [
168+
{
169+
action: 'c2pa.created',
170+
},
171+
],
172+
},
173+
},
174+
{
175+
label: 'com.custom.my-assertion',
176+
data: {
177+
description: 'My custom test assertion',
178+
version: '1.0.0',
179+
},
180+
},
181+
],
182+
},
183+
{ vendor: 'cai' },
184+
);
185+
186+
// sign
187+
await sign(asset, manifest);
188+
```
189+
190+
## Remote signing
191+
192+
If you have access to a web service that performs signing, you can use it to sign remotely; for example:
193+
194+
```ts
195+
import { readFile } from 'node:fs/promises';
196+
import { fetch, Headers } from 'node-fetch';
197+
import { createC2pa, SigningAlgorithm } from 'c2pa-node';
198+
199+
function createRemoteSigner() {
200+
return {
201+
type: 'remote',
202+
async reserveSize() {
203+
const url = `https://my.signing.service/box-size`;
204+
const res = await fetch(url);
205+
const data = (await res.json()) as { boxSize: number };
206+
return data.boxSize;
207+
},
208+
async sign({ reserveSize, toBeSigned }) {
209+
const url = `https://my.signing.service/sign?boxSize=${reserveSize}`;
210+
const res = await fetch(url, {
211+
method: 'POST',
212+
headers: new Headers({
213+
'Content-Type': 'application/octet-stream',
214+
}),
215+
body: toBeSigned,
216+
});
217+
return res.buffer();
218+
},
219+
};
220+
}
221+
222+
async function sign(asset, manifest) {
223+
const signer = createRemoteSigner();
224+
const c2pa = createC2pa({
225+
signer,
226+
});
227+
228+
const { signedAsset, signedManifest } = await c2pa.sign({
229+
asset,
230+
manifest,
231+
});
232+
}
233+
234+
const buffer = await readFile('to-be-signed.jpg');
235+
const asset: Asset = { buffer, mimeType: 'image/jpeg' };
236+
237+
const manifest = new ManifestBuilder(
238+
{
239+
claim_generator: 'my-app/1.0.0',
240+
format: 'image/jpeg',
241+
title: 'buffer_signer.jpg',
242+
assertions: [
243+
{
244+
label: 'c2pa.actions',
245+
data: {
246+
actions: [
247+
{
248+
action: 'c2pa.created',
249+
},
250+
],
251+
},
252+
},
253+
{
254+
label: 'com.custom.my-assertion',
255+
data: {
256+
description: 'My custom test assertion',
257+
version: '1.0.0',
258+
},
259+
},
260+
],
261+
},
262+
{ vendor: 'cai' },
263+
);
264+
265+
await sign(asset, manifest);
266+
```
267+
16268
</TabItem>
17269

18270
<TabItem value="cpp" label="C++">

0 commit comments

Comments
 (0)