| 754 | // ========================================================================= |
| 755 | // Worksheet Protection |
| 756 | protect(password, options) { |
| 757 | // TODO: make this function truly async |
| 758 | // perhaps marshal to worker thread or something |
| 759 | return new Promise(resolve => { |
| 760 | this.sheetProtection = { |
| 761 | sheet: true, |
| 762 | }; |
| 763 | if (options && 'spinCount' in options) { |
| 764 | // force spinCount to be integer >= 0 |
| 765 | options.spinCount = Number.isFinite(options.spinCount) ? Math.round(Math.max(0, options.spinCount)) : 100000; |
| 766 | } |
| 767 | if (password) { |
| 768 | this.sheetProtection.algorithmName = 'SHA-512'; |
| 769 | this.sheetProtection.saltValue = Encryptor.randomBytes(16).toString('base64'); |
| 770 | this.sheetProtection.spinCount = options && 'spinCount' in options ? options.spinCount : 100000; // allow user specified spinCount |
| 771 | this.sheetProtection.hashValue = Encryptor.convertPasswordToHash( |
| 772 | password, |
| 773 | 'SHA512', |
| 774 | this.sheetProtection.saltValue, |
| 775 | this.sheetProtection.spinCount |
| 776 | ); |
| 777 | } |
| 778 | if (options) { |
| 779 | this.sheetProtection = Object.assign(this.sheetProtection, options); |
| 780 | if (!password && 'spinCount' in options) { |
| 781 | delete this.sheetProtection.spinCount; |
| 782 | } |
| 783 | } |
| 784 | resolve(); |
| 785 | }); |
| 786 | } |
| 787 | |
| 788 | unprotect() { |
| 789 | this.sheetProtection = null; |