VulpesOS/assets/webapps/settings.gaiamobile.org/shared/js/passcode_helper.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

14 lines
No EOL
3.1 KiB
JavaScript

(function(exports){'use strict';const SET_DIGEST_VALUE='lockscreen.passcode-lock.digest.value';const SET_DIGEST_SALT='lockscreen.passcode-lock.digest.salt';const SET_DIGEST_ITERATIONS='lockscreen.passcode-lock.digest.iterations';const SET_DIGEST_ALGORITHM='lockscreen.passcode-lock.digest.algorithm';const DEFAULT_ALGORITHM='SHA-1';const DEFAULT_ITERATIONS=1000;const PBKDF2_OUTPUT_LENGTH=160;function _encode(str){return new TextEncoder('utf-8').encode(str);}
function _toTypedArray(obj){var a=[];for(var key of Object.keys(obj)){a.push(obj[key]);}
return new Uint8Array(a);}
function _deriveBits(pwKey,salt,iterations,algorithm){var params={name:'PBKDF2',hash:algorithm,salt:salt,iterations:iterations};return crypto.subtle.deriveBits(params,pwKey,PBKDF2_OUTPUT_LENGTH);}
function _makeDigest(pass,salt,iterations,algorithm){var bytes=_encode(pass);var promise=crypto.subtle.importKey('raw',bytes,'PBKDF2',false,['deriveBits']);promise=promise.then((pwKey)=>{return _deriveBits(pwKey,salt,iterations,algorithm);});promise=promise.catch((error)=>{console.error('PasscodeHelper: _derive_bits() failed!',error);throw error;});return promise;}
function setPasscode(newPass){var salt=crypto.getRandomValues(new Uint8Array(8));var promise=_makeDigest(newPass,salt,DEFAULT_ITERATIONS,DEFAULT_ALGORITHM);promise=promise.then((digest)=>{return _storeNewPasscode(digest,salt);});promise=promise.catch((error)=>{console.error('PasscodeHelper: Could not make digest:',error);throw error;});return promise;}
function _storeNewPasscode(digest,salt){var digestUint8=new Uint8Array(digest);var newSettings={[SET_DIGEST_SALT]:salt,[SET_DIGEST_VALUE]:digestUint8,[SET_DIGEST_ITERATIONS]:DEFAULT_ITERATIONS,[SET_DIGEST_ALGORITHM]:DEFAULT_ALGORITHM,};var lock=navigator.mozSettings.createLock();var req=lock.set(newSettings);return req.then(()=>{return digestUint8;},(error)=>{console.error('PasscodeHelper: Couldnt store new digest',error);throw error;});}
function checkPasscode(testPass){var lock=navigator.mozSettings.createLock();var storedParams=Promise.all([lock.get(SET_DIGEST_SALT),lock.get(SET_DIGEST_ITERATIONS),lock.get(SET_DIGEST_ALGORITHM),lock.get(SET_DIGEST_VALUE)]);return storedParams.then((values)=>{return _makeAndCompare(...values,testPass);}).catch((error)=>{console.error('PasscodeHelper: Couldnt get digest Settings:',error);throw error;});}
function _makeAndCompare(salt,iterations,algorithm,storedDigest,testPass){var _salt=_toTypedArray(salt[SET_DIGEST_SALT]);var _iterations=iterations[SET_DIGEST_ITERATIONS];var _algorithm=algorithm[SET_DIGEST_ALGORITHM];var _storedDigest=_toTypedArray(storedDigest[SET_DIGEST_VALUE]);var promise=_makeDigest(testPass,_salt,_iterations,_algorithm);promise=promise.then((digest)=>{var typedDigest=new Uint8Array(digest);return _compareDigests(_storedDigest,typedDigest);});promise=promise.catch((error)=>{console.error('PasscodeHelper: Couldnt create digest',error);throw error;});return promise;}
function _compareDigests(buf1,buf2){if(buf1.byteLength!==buf2.byteLength){return false;}
for(var i=0;i<buf1.byteLength;i++){if(buf1[i]!==buf2[i]){return false;}}
return true;}
exports.PasscodeHelper={set:setPasscode,check:checkPasscode};})(this);