first commit
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Types tests / Test (lts/*) (push) Has been cancelled
				
			
		
			
				
	
				Lint / Lint (lts/*) (push) Has been cancelled
				
			
		
			
				
	
				CodeQL / Analyze (javascript) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (20) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (22) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (24) (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Types tests / Test (lts/*) (push) Has been cancelled
				
			Lint / Lint (lts/*) (push) Has been cancelled
				
			CodeQL / Analyze (javascript) (push) Has been cancelled
				
			CI / Test (20) (push) Has been cancelled
				
			CI / Test (22) (push) Has been cancelled
				
			CI / Test (24) (push) Has been cancelled
				
			This commit is contained in:
		
							
								
								
									
										103
									
								
								web/generic_signature_storage.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								web/generic_signature_storage.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
/* Copyright 2025 Mozilla Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { getUuid } from "pdfjs-lib";
 | 
			
		||||
 | 
			
		||||
const KEY_STORAGE = "pdfjs.signature";
 | 
			
		||||
 | 
			
		||||
class SignatureStorage {
 | 
			
		||||
  // TODO: Encrypt the data in using a password and add a UI for entering it.
 | 
			
		||||
  // We could use the Web Crypto API for this (see https://bradyjoslin.com/blog/encryption-webcrypto/
 | 
			
		||||
  // for an example).
 | 
			
		||||
 | 
			
		||||
  #eventBus;
 | 
			
		||||
 | 
			
		||||
  #signatures = null;
 | 
			
		||||
 | 
			
		||||
  #signal = null;
 | 
			
		||||
 | 
			
		||||
  constructor(eventBus, signal) {
 | 
			
		||||
    this.#eventBus = eventBus;
 | 
			
		||||
    this.#signal = signal;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #save() {
 | 
			
		||||
    localStorage.setItem(
 | 
			
		||||
      KEY_STORAGE,
 | 
			
		||||
      JSON.stringify(Object.fromEntries(this.#signatures))
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getAll() {
 | 
			
		||||
    if (this.#signal) {
 | 
			
		||||
      window.addEventListener(
 | 
			
		||||
        "storage",
 | 
			
		||||
        ({ key }) => {
 | 
			
		||||
          if (key === KEY_STORAGE) {
 | 
			
		||||
            this.#signatures = null;
 | 
			
		||||
            this.#eventBus?.dispatch("storedsignatureschanged", {
 | 
			
		||||
              source: this,
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        { signal: this.#signal }
 | 
			
		||||
      );
 | 
			
		||||
      this.#signal = null;
 | 
			
		||||
    }
 | 
			
		||||
    if (!this.#signatures) {
 | 
			
		||||
      this.#signatures = new Map();
 | 
			
		||||
      const data = localStorage.getItem(KEY_STORAGE);
 | 
			
		||||
      if (data) {
 | 
			
		||||
        for (const [key, value] of Object.entries(JSON.parse(data))) {
 | 
			
		||||
          this.#signatures.set(key, value);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return this.#signatures;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async isFull() {
 | 
			
		||||
    // Only allow 5 signatures to be saved.
 | 
			
		||||
    return (await this.size()) === 5;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async size() {
 | 
			
		||||
    return (await this.getAll()).size;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async create(data) {
 | 
			
		||||
    if (await this.isFull()) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    const uuid = getUuid();
 | 
			
		||||
    this.#signatures.set(uuid, data);
 | 
			
		||||
    this.#save();
 | 
			
		||||
 | 
			
		||||
    return uuid;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async delete(uuid) {
 | 
			
		||||
    const signatures = await this.getAll();
 | 
			
		||||
    if (!signatures.has(uuid)) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    signatures.delete(uuid);
 | 
			
		||||
    this.#save();
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { SignatureStorage };
 | 
			
		||||
		Reference in New Issue
	
	Block a user