Skip to content

Commit

Permalink
Allow calling initialize() only once
Browse files Browse the repository at this point in the history
WasmThemis initialization fills in the "context.libthemis" singleton
that is actually used by all WasmThemis functions. That is, calling
initialize() multiple times is technically permitted, but it might not
have an effect that you expect. WasmThemis will always use WebAssembly
context from the last initialization.

While reinitialization might be useful, it does not seem to be now.
Let's allow calling initialize() only once. (This includes calling it
indirectly via the "initialized" promise.) We can always allow it later,
once the semantics of this are clarified.
  • Loading branch information
ilammy committed Jul 13, 2021
1 parent 40b3346 commit 62fb719
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/wrappers/themis/wasm/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import context from "./context";
import libthemisFn from "./libthemis.js";
import { ThemisError, ThemisErrorCode } from "./themis_error";

export { SecureCellSeal } from "./secure_cell_seal";
export { SecureCellTokenProtect } from "./secure_cell_token_protect";
Expand Down Expand Up @@ -41,6 +42,8 @@ let onRuntimeInitialized: () => void
// is expected to call, then await the result to resolve before using
// other WasmThemis functions.

let libthemisInitialized = false;

/**
* Initialize WasmThemis.
*
Expand All @@ -54,15 +57,26 @@ let onRuntimeInitialized: () => void
*
* @param wasmPath URL of `libthemis.wasm` to download.
*
* @throws {ThemisError} is thrown if this function is called more than once,
* or if WasmThemis has been already initialized via `initialized`.
*
* @since WasmThemis 0.14.0
*/
export const initialize = async (wasmPath?: string) => {
if (libthemisInitialized) {
throw new ThemisError(
'initialize',
ThemisErrorCode.FAIL,
'WasmThemis can only be initalized once',
);
}
context.libthemis = await libthemisFn({
onRuntimeInitialized: () => onRuntimeInitialized(),
locateFile: wasmPath ? function () {
return wasmPath;
} : undefined,
});
libthemisInitialized = true;

return context.libthemis;
};
Expand Down Expand Up @@ -144,6 +158,9 @@ class InitializedPromise {
* in the same directory as the executing script.
* If you need to use a custom location, call `initialize()`.
*
* Note that you cannot use `initialize()` after WasmThemis has been initialized
* using this promise.
*
* @see initialize
*/
export const initialized = new InitializedPromise((resolve) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const themis = require('../../src/index.ts')
const ThemisErrorCode = themis.ThemisErrorCode
const assert = require('assert')

describe('wasm-themis', function() {
Expand All @@ -16,5 +17,11 @@ describe('wasm-themis', function() {
done()
})
})
it('can only be initialized once', function(done) {
themis.initialize('src/libthemis.wasm').catch(function(e) {
assert.strictEqual(e.errorCode, ThemisErrorCode.FAIL)
done()
})
})
})
})
7 changes: 7 additions & 0 deletions src/wrappers/themis/wasm/test/initialization/initialize.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const themis = require('../../src/index.ts')
const ThemisErrorCode = themis.ThemisErrorCode
const assert = require('assert')

describe('wasm-themis', function() {
Expand All @@ -10,5 +11,11 @@ describe('wasm-themis', function() {
done()
})
})
it('can only be initialized once', function(done) {
themis.initialize().catch(function(e) {
assert.strictEqual(e.errorCode, ThemisErrorCode.FAIL)
done()
})
})
})
})
8 changes: 8 additions & 0 deletions src/wrappers/themis/wasm/test/initialization/initialized.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const themis = require('../../src/index.ts')
const ThemisErrorCode = themis.ThemisErrorCode
const assert = require('assert')

describe('wasm-themis', function() {
Expand All @@ -10,5 +11,12 @@ describe('wasm-themis', function() {
done()
})
})
// "themis.initialized" stays resolved but you cannot initialize again.
it('can only be initialized once', function(done) {
themis.initialize().catch(function(e) {
assert.strictEqual(e.errorCode, ThemisErrorCode.FAIL)
done()
})
})
})
})

0 comments on commit 62fb719

Please sign in to comment.