@@ -6,7 +6,12 @@ import { KasPublicKeyAlgorithm } from '../../src/access.js';
66import { AuthProvider , HttpRequest } from '../../src/auth/auth.js' ;
77import { AesGcmCipher , KeyInfo , SplitKey , WebCryptoService } from '../../tdf3/index.js' ;
88import { Client } from '../../tdf3/src/index.js' ;
9- import { AssertionConfig , AssertionVerificationKeys } from '../../tdf3/src/assertions.js' ;
9+ import {
10+ AssertionConfig ,
11+ AssertionVerificationKeys ,
12+ getSystemMetadataAssertionConfig ,
13+ Assertion ,
14+ } from '../../tdf3/src/assertions.js' ;
1015import { Scope } from '../../tdf3/src/client/builders.js' ;
1116import { NetworkError } from '../../src/errors.js' ;
1217
@@ -364,4 +369,124 @@ describe('encrypt decrypt test', async function () {
364369 } ) ;
365370 }
366371 }
372+
373+ it ( 'encrypt-decrypt with system metadata assertion' , async function ( ) {
374+ const cipher = new AesGcmCipher ( WebCryptoService ) ;
375+ const encryptionInformation = new SplitKey ( cipher ) ;
376+ const key1 = await encryptionInformation . generateKey ( ) ;
377+ const keyMiddleware = async ( ) => ( { keyForEncryption : key1 , keyForManifest : key1 } ) ;
378+
379+ const client = new Client . Client ( {
380+ kasEndpoint : kasUrl ,
381+ platformUrl : kasUrl ,
382+ dpopKeys : Mocks . entityKeyPair ( ) ,
383+ clientId : 'id' ,
384+ authProvider,
385+ } ) ;
386+
387+ const scope : Scope = {
388+ 389+ attributes : [ ] ,
390+ } ;
391+
392+ const encryptedStream = await client . encrypt ( {
393+ metadata : Mocks . getMetadataObject ( ) ,
394+ wrappingKeyAlgorithm : 'rsa:2048' ,
395+ offline : true ,
396+ scope,
397+ keyMiddleware,
398+ source : new ReadableStream ( {
399+ start ( controller ) {
400+ controller . enqueue ( new TextEncoder ( ) . encode ( expectedVal ) ) ;
401+ controller . close ( ) ;
402+ } ,
403+ } ) ,
404+ systemMetadataAssertion : true , // Enable the system metadata assertion
405+ } ) ;
406+
407+ // Consume the stream into a buffer. This also ensures manifest population is complete.
408+ const encryptedTdfBuffer = await encryptedStream . toBuffer ( ) ;
409+
410+ // Verify the manifest for the system metadata assertion
411+ const manifest = encryptedStream . manifest ;
412+ assert . isArray ( manifest . assertions , 'Manifest assertions should be an array' ) ;
413+ assert . lengthOf ( manifest . assertions , 1 , 'Should have one assertion for system metadata' ) ;
414+
415+ const systemAssertion = manifest . assertions . find (
416+ ( assertion : Assertion ) => assertion . id === 'system-metadata'
417+ ) ;
418+ assert . isDefined ( systemAssertion , 'System metadata assertion should be found' ) ;
419+ if ( systemAssertion ) {
420+ assert . equal ( systemAssertion . type , 'other' , 'Assertion type should be "other"' ) ;
421+ assert . equal ( systemAssertion . scope , 'tdo' , 'Assertion scope should be "tdo"' ) ;
422+ assert . equal ( systemAssertion . statement . format , 'json' , 'Statement format should be "json"' ) ;
423+ assert . equal (
424+ systemAssertion . statement . schema ,
425+ 'system-metadata-v1' ,
426+ 'Statement schema should be "system-metadata-v1"'
427+ ) ;
428+
429+ const metadataValue = JSON . parse ( systemAssertion . statement . value ) ;
430+ assert . property ( metadataValue , 'tdf_spec_version' , 'Metadata should have tdfSpecVersion' ) ;
431+ assert . property ( metadataValue , 'creation_date' , 'Metadata should have creationDate' ) ;
432+ assert . property ( metadataValue , 'sdk_version' , 'Metadata should have sdkVersion' ) ;
433+ assert . property ( metadataValue , 'browser_user_agent' , 'Metadata should have browserUserAgent' ) ;
434+ assert . property ( metadataValue , 'platform' , 'Metadata should have platform' ) ;
435+
436+ // Compare Values
437+ const systemMetadata = getSystemMetadataAssertionConfig ( ) ;
438+ assert . equal ( systemMetadata . id , systemAssertion . id , 'ID should match' ) ;
439+ assert . equal ( systemMetadata . type , systemAssertion . type , 'Type should match' ) ;
440+ assert . equal ( systemMetadata . scope , systemAssertion . scope , 'Scope should match' ) ;
441+ assert . equal (
442+ systemMetadata . statement . format ,
443+ systemAssertion . statement . format ,
444+ 'Statement format should match'
445+ ) ;
446+ assert . equal (
447+ systemMetadata . statement . schema ,
448+ systemAssertion . statement . schema ,
449+ 'Statement schema should match'
450+ ) ;
451+ assert . equal (
452+ systemMetadata . appliesToState ,
453+ systemAssertion . appliesToState ,
454+ 'AppliesToState should match'
455+ ) ;
456+
457+ // Parse statement.value and compare individual fields, ignoring creationDate for direct equality
458+ const expectedMetadataValue = JSON . parse ( systemMetadata . statement . value ) ;
459+ const actualMetadataValue = JSON . parse ( systemAssertion . statement . value ) ;
460+
461+ assert . isString ( actualMetadataValue . creation_date , 'creation_date should be a string' ) ;
462+ assert . isNotEmpty ( actualMetadataValue . creation_date , 'creation_date should not be empty' ) ;
463+ assert . equal (
464+ actualMetadataValue . tdf_spec_version ,
465+ expectedMetadataValue . tdf_spec_version ,
466+ 'tdf_spec_version should match'
467+ ) ;
468+ assert . equal (
469+ actualMetadataValue . sdk_version ,
470+ expectedMetadataValue . sdk_version ,
471+ 'sdk_version should match'
472+ ) ;
473+ assert . equal (
474+ actualMetadataValue . browser_user_agent ,
475+ expectedMetadataValue . browser_user_agent ,
476+ 'browser_user_agent should match'
477+ ) ;
478+ assert . equal (
479+ actualMetadataValue . platform ,
480+ expectedMetadataValue . platform ,
481+ 'platform should match'
482+ ) ;
483+ }
484+
485+ const decryptStream = await client . decrypt ( {
486+ source : { type : 'buffer' , location : encryptedTdfBuffer } ,
487+ } ) ;
488+
489+ const { value : decryptedText } = await decryptStream . stream . getReader ( ) . read ( ) ;
490+ assert . equal ( new TextDecoder ( ) . decode ( decryptedText ) , expectedVal ) ;
491+ } ) ;
367492} ) ;
0 commit comments