threepipe
Version:
A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.
66 lines • 2.84 kB
JavaScript
import { aesGcmDecrypt, aesGcmEncrypt, getOrCall } from 'ts-browser-helpers';
import { makeGLBFile } from '../../utils';
import { GLTFBinaryExtension } from 'three/examples/jsm/loaders/GLTFLoader.js';
/**
* Sample encryption processor for {@link GLTFExporter2} that wraps the glb in a new glb with encrypted content and encryption metadata.
* Uses AES-GCM ({@link aesGcmEncrypt}) for encryption since it is widely supported across browsers and js environments.
* @param gltf
* @param options
*/
export const glbEncryptionProcessor = async (gltf, options) => {
if (!gltf || !(gltf instanceof ArrayBuffer) || !gltf.byteLength || !options.encrypt)
return gltf;
if (!options.encryptKey && window && window.prompt) {
options.encryptKey = window.prompt('GLTFEncryption: Enter encryption key/password') || '';
}
if (!options.encryptKey) {
console.warn('GLTF Export: encryption key not provided, skipping encryption');
return gltf;
}
const buffer = await aesGcmEncrypt(new Uint8Array(gltf), options.encryptKey);
return makeGLBFile(buffer, {
asset: {
version: '2.0',
generator: 'ThreePipeGLBWrapper',
encryption: {
type: 'aesgcm',
version: 1,
},
},
});
};
/**
* Sample encryption preparser for {@link GLTFLoader2} that unwraps the glb container and decrypts the content. The encryption key can be provided in the file or set in this const is prompted from the user.
*/
export const glbEncryptionPreparser = {
key: (encryption, _, path) => {
return encryption.key || window && window.prompt && window.prompt('GLTFEncryption: Please enter the password/key for the model: ' + path) || '';
},
async process(data, path) {
if (typeof data === 'string')
return data;
const prefixBytes = 100;
const prefix = new TextDecoder().decode(new Uint8Array(data, 0, prefixBytes));
if (!prefix.includes('GLBWrapper'))
return data;
const binaryExtension = new GLTFBinaryExtension(data);
const json = JSON.parse(binaryExtension.content || '{}');
let data2 = binaryExtension.body || data;
const encryption = json.asset?.encryption;
if (!encryption)
return data2;
const type = encryption.type;
const version = encryption.version;
if (type === 'aesgcm' && version === 1) {
const key = await getOrCall(this.key, encryption, json, path) || '';
try {
data2 = (await aesGcmDecrypt(new Uint8Array(data2), key)).buffer;
}
catch (e) {
throw new ErrorEvent('decryption error');
}
}
return data2;
},
};
//# sourceMappingURL=gltfEncyptionHelpers.js.map