@lo-fi/local-data-lock
Advanced tools
Comparing version 0.13.2 to 0.14.0
@@ -1,6 +0,6 @@ | ||
/*! Local-Data-Lock: ldl.js | ||
v0.13.2 (c) 2024 Kyle Simpson | ||
/*! mylofi/Local-Data-Lock: ldl.js | ||
v0.14.0 (c) 2024 Kyle Simpson | ||
MIT License: http://getify.mit-license.org | ||
*/ | ||
import{supportsWebAuthn as e,regDefaults as t,register as r,authDefaults as a,auth as n,verifyAuthResponse as i,packPublicKeyJSON as o,unpackPublicKeyJSON as c,toBase64String as l,fromBase64String as s,toUTF8String as y,fromUTF8String as u,resetAbortReason as f}from"@lo-fi/webauthn-local-client";const p=1,d=sodium.crypto_sign_SEEDBYTES;var g=setLockKeyCacheLifetime(18e5),k="idb",b=null,h=null,w={},m=null,K=new WeakMap;export{e as supportsWebAuthn,o as packPublicKeyJSON,c as unpackPublicKeyJSON,l as toBase64String,s as fromBase64String,y as toUTF8String,u as fromUTF8String,f as resetAbortReason,listLocalIdentities,clearLockKeyCache,removeLocalAccount,getLockKey,generateEntropy,deriveLockKey,lockData,unlockData,signData,verifySignature,configure};var L={supportsWebAuthn:e,packPublicKeyJSON:o,unpackPublicKeyJSON:c,toBase64String:l,fromBase64String:s,toUTF8String:y,fromUTF8String:u,resetAbortReason:f,listLocalIdentities:listLocalIdentities,clearLockKeyCache:clearLockKeyCache,removeLocalAccount:removeLocalAccount,getLockKey:getLockKey,generateEntropy:generateEntropy,deriveLockKey:deriveLockKey,lockData:lockData,unlockData:unlockData,signData:signData,verifySignature:verifySignature,configure:configure};export default L;async function listLocalIdentities(){return await checkStorage(),Object.keys(h)}function cacheLockKey(e,t,r=!1){e in w&&!r||(w[e]={...t,timestamp:Date.now()})}function clearLockKeyCache(e){null!=e?delete w[e]:w={}}async function removeLocalAccount(e){return await checkStorage(),delete w[e],delete h[e],storeLocalIdentities()}async function getLockKey({localIdentity:e=l(generateEntropy(15)),username:o="local-user",displayName:c="Local User",relyingPartyID:s=document.location.hostname,relyingPartyName:y="Local Data Lock",addNewPasskey:u=!1,resetLockKey:f=!1,useLockKey:p=null,verify:k=!0,signal:b}={}){await checkStorage();var K=null!=e?h[e]:null;if(null!=K){let t=function getCachedLockKey(e){var t=Date.now();if(e in w&&w[e].timestamp>=t-Math.min(g,t)){let{timestamp:t,...r}=w[e];return r}}(e);if(null!=t&&!f){if(u){resetAbortToken(b);let{record:e}=await registerLocalIdentity(t)||{};cleanupExternalSignalHandler(m),m=null,null!=e&&(K.lastSeq=e.lastSeq,K.passkeys=[...K.passkeys,...e.passkeys],await storeLocalIdentities())}return Object.freeze({...t,localIdentity:e})}if(delete w[e],f){if(resetAbortToken(b),({record:h[e],lockKey:t}=await registerLocalIdentity(p&&"object"==typeof p?checkLockKey(p):void 0)),cleanupExternalSignalHandler(m),m=null,null==h[e])delete h[e];else if(null!=t)return await storeLocalIdentities(),cacheLockKey(e,t),Object.freeze({...t,localIdentity:e})}else{if(u)throw new Error("Encryption/Decryption key not currently cached, unavailable for new passkey");{resetAbortToken(b);let t=a({relyingPartyID:s,mediation:"optional",allowCredentials:K.passkeys.map((({credentialID:e})=>({type:"public-key",id:e}))),signal:m.signal}),r=await n(t);if(cleanupExternalSignalHandler(m),m=null,null!=r){if(k){let e=K.passkeys.find((e=>e.credentialID==r.response.credentialID)),t=e?.publicKey;if(!(null!=t&&await i(r.response,t)))throw new Error("Auth verification failed")}return{...extractLockKey(r),localIdentity:e}}}}}else if(u){resetAbortToken(b);let{record:t,lockKey:r}=await registerLocalIdentity(p&&"object"==typeof p?checkLockKey(p):void 0)||{};if(cleanupExternalSignalHandler(m),m=null,null!=t&&null!=r)return h[e]=t,cacheLockKey(e,r),await storeLocalIdentities(),Object.freeze({...r,localIdentity:e})}else{resetAbortToken(b);let t=a({relyingPartyID:s,mediation:"optional",signal:m.signal}),r=await n(t);if(cleanupExternalSignalHandler(m),m=null,null!=r){let t=extractLockKey(r),[a]=Object.entries(h).find((([,e])=>null!=e.passkeys.find((e=>e.credentialID==r.response.credentialID))))||[];if(null!=a){if(delete w[e],K=h[e=a],k){let e=K.passkeys.find((e=>e.credentialID==r.response.credentialID)),t=e?.publicKey;if(!(null!=t&&await i(r.response,t)))throw new Error("Auth verification failed")}cacheLockKey(e,t)}else if(k)throw new Error("Auth verification requested but skipped, against unrecognized passkey (no matching local-identity)");return Object.freeze({...t,localIdentity:e})}}async function registerLocalIdentity(a=deriveLockKey()){try{let i=((h[e]||{}).lastSeq||0)+1,l=new Uint8Array(a.iv.byteLength+2),u=new DataView(new ArrayBuffer(2));u.setInt16(0,i,!1),l.set(a.iv,0),l.set(new Uint8Array(u.buffer),a.iv.byteLength);let f=t({relyingPartyID:s,relyingPartyName:y,user:{id:l,name:o,displayName:c},signal:m.signal}),p=await r(f);if(null!=p)return{record:{lastSeq:i,passkeys:[(n={seq:i,credentialID:p.response.credentialID,publicKey:p.response.publicKey},{...n,hash:computePasskeyEntryHash(n)})]},lockKey:a}}catch(e){throw new Error("Identity/Passkey registration failed",{cause:e})}var n}function extractLockKey(t){try{if(t&&t.response&&isByteArray(t.response.userID)&&t.response.userID.byteLength==d+2){let r=deriveLockKey(t.response.userID.subarray(0,d));return cacheLockKey(e,r),r}throw new Error("Passkey info missing")}catch(e){throw new Error("Chosen passkey did not provide a valid encryption/decryption key",{cause:e})}}}function resetAbortToken(e){if(m&&(cleanupExternalSignalHandler(m),m.aborted||m.abort("Passkey operation abandoned.")),m=new AbortController,null!=e)if(e.aborted)m.abort(e.reason);else{let handlerFn=()=>{cleanupExternalSignalHandler(m),m.abort(e.reason),m=e=handlerFn=null};e.addEventListener("abort",handlerFn),K.set(m,[e,handlerFn])}}function cleanupExternalSignalHandler(e){if(null!=e&&K.has(e)){let[t,r]=K.get(e);t.removeEventListener("abort",r),K.delete(e)}}function generateEntropy(e=16){return sodium.randombytes_buf(e)}function deriveLockKey(e=generateEntropy(d)){try{let t=sodium.crypto_sign_seed_keypair(e);return{keyFormatVersion:p,iv:e,publicKey:t.publicKey,privateKey:t.privateKey,encPK:sodium.crypto_sign_ed25519_pk_to_curve25519(t.publicKey),encSK:sodium.crypto_sign_ed25519_sk_to_curve25519(t.privateKey)}}catch(e){throw new Error("Encryption/decryption key derivation failed.",{cause:e})}}function checkLockKey(e){if(e&&"object"==typeof e){if(e.keyFormatVersion===p)return e;if(isByteArray(e.iv)&&e.iv.byteLength==d)return deriveLockKey(e.iv)}throw new Error("Unrecongnized lock-key")}function lockData(e,t,{outputFormat:r="base64"}={}){try{let a=dataToBuffer(e),n=sodium.crypto_box_seal(a,t.encPK);return["base64","base-64"].includes(r.toLowerCase())?l(n):n}catch(e){throw new Error("Data encryption failed.",{cause:e})}}function unlockData(e,t,{outputFormat:r="utf8",parseJSON:a=!0}={}){try{let n=sodium.crypto_box_seal_open("string"==typeof e?s(e):e,t.encPK,t.encSK);if(["utf8","utf-8"].includes(r.toLowerCase())){let e=y(n);return a?JSON.parse(e):e}return n}catch(e){throw new Error("Data decryption failed.",{cause:e})}}function signData(e,{privateKey:t}={},{outputFormat:r="base64"}={}){try{let a=sodium.crypto_sign_detached(dataToBuffer(e),t);return["base64","base-64"].includes(r.toLowerCase())?l(a):a}catch(e){throw new Error("Data signature failed.",{cause:e})}}function verifySignature(e,{publicKey:t}={},r){try{return sodium.crypto_sign_verify_detached("string"==typeof r?s(r):r,dataToBuffer(e),t)}catch(e){throw new Error("Data signature failed.",{cause:e})}}async function storeLocalIdentities(){await checkStorage();var e=Object.fromEntries(Object.entries(h).map((([e,t])=>[e,{...t,passkeys:t.passkeys.map((e=>({...e,publicKey:o(e.publicKey)})))}])));Object.keys(e).length>0?await b.set("local-identities",e):await b.remove("local-identities")}function setLockKeyCacheLifetime(e){return g=Math.max(0,Number(e)||0)}function configure({accountStorage:e,cacheLifetime:t}={}){null!=e&&function configureStorage(e){if(["idb","local-storage","session-storage","cookie","opfs","opfs-worker"].includes(e))k=e,h=b=null;else{if("object"!=typeof e||"string"!=typeof e.storageType||!["has","get","set","remove","keys","entries"].every((t=>"function"==typeof e[t])))throw new Error(`Unrecognized storage type ('${storageType}')`);b=e,k=e.storageType,h=null}}(e),null!=t&&setLockKeyCacheLifetime(t)}function dataToBuffer(e){var t=null==e?null:e instanceof ArrayBuffer?new Uint8Array(e):isByteArray(e)?e:u("object"==typeof e?JSON.stringify(e):"string"==typeof e?e:String(e));if(null==t)throw new Error("Non-empty data required.");return t}function isByteArray(e){return e instanceof Uint8Array&&e.buffer instanceof ArrayBuffer}function computePasskeyEntryHash(e){let{hash:t,...r}=e;return l(sodium.crypto_hash(JSON.stringify({...r,publicKey:o(r.publicKey)})))}async function checkStorage(){if(null==b){if(!["idb","local-storage","session-storage","cookie","opfs","opfs-worker"].includes(k))throw new Error(`Unrecognized storage type ('${k}')`);b="idb"==k?await import("@lo-fi/client-storage/idb"):"local-storage"==k?await import("@lo-fi/client-storage/local-storage"):"session-storage"==k?await import("@lo-fi/client-storage/session-storage"):"cookie"==k?await import("@lo-fi/client-storage/cookie"):"opfs"==k?await import("@lo-fi/client-storage/opfs"):"opfs-worker"==k?await import("@lo-fi/client-storage/opfs-worker"):null}null!=b&&null==h&&(h=await async function loadLocalIdentities(){return Object.fromEntries(Object.entries(await b.get("local-identities")||{}).filter((([e,t])=>"number"==typeof t.lastSeq&&Array.isArray(t.passkeys)&&t.passkeys.length>0&&t.passkeys.every((e=>"string"==typeof e.credentialID&&""!=e.credentialID&&"number"==typeof e.seq&&null!=e.publicKey&&"object"==typeof e.publicKey&&"number"==typeof e.publicKey.algoCOSE&&"string"==typeof e.publicKey.raw&&""!=e.publicKey.raw&&"string"==typeof e.publicKey.spki&&""!=e.publicKey.spki&&"string"==typeof e.hash&&""!=e.hash&&e.hash==computePasskeyEntryHash(e))))).map((([e,t])=>[e,{...t,passkeys:t.passkeys.map((e=>({...e,publicKey:c(e.publicKey)})))}])))}())} | ||
import{supportsWebAuthn as e,regDefaults as t,register as r,authDefaults as a,auth as n,verifyAuthResponse as o,packPublicKeyJSON as i,unpackPublicKeyJSON as s,toBase64String as c,fromBase64String as l,toUTF8String as y,fromUTF8String as u,resetAbortReason as p}from"@lo-fi/webauthn-local-client";const f=1,d=sodium.crypto_sign_SEEDBYTES;var g=setLockKeyCacheLifetime(18e5),k="idb",b=null,h=null,w={},m=null,K=new WeakMap;export{e as supportsWebAuthn,i as packPublicKeyJSON,s as unpackPublicKeyJSON,c as toBase64String,l as fromBase64String,y as toUTF8String,u as fromUTF8String,p as resetAbortReason,listLocalIdentities,clearLockKeyCache,removeLocalAccount,getLockKey,generateEntropy,deriveLockKey,lockData,unlockData,signData,verifySignature,configure};var L={supportsWebAuthn:e,packPublicKeyJSON:i,unpackPublicKeyJSON:s,toBase64String:c,fromBase64String:l,toUTF8String:y,fromUTF8String:u,resetAbortReason:p,listLocalIdentities:listLocalIdentities,clearLockKeyCache:clearLockKeyCache,removeLocalAccount:removeLocalAccount,getLockKey:getLockKey,generateEntropy:generateEntropy,deriveLockKey:deriveLockKey,lockData:lockData,unlockData:unlockData,signData:signData,verifySignature:verifySignature,configure:configure};export default L;async function listLocalIdentities(){return await checkStorage(),Object.keys(h)}function cacheLockKey(e,t,r=!1){e in w&&!r||(w[e]={...t,timestamp:Date.now()})}function clearLockKeyCache(e){null!=e?delete w[e]:w={}}async function removeLocalAccount(e){return await checkStorage(),delete w[e],delete h[e],storeLocalIdentities()}async function getLockKey({localIdentity:e=c(generateEntropy(15)),username:i="local-user",displayName:s="Local User",relyingPartyID:l=document.location.hostname,relyingPartyName:y="Local Data Lock",addNewPasskey:u=!1,resetLockKey:p=!1,useLockKey:f=null,verify:k=!0,signal:b}={}){await checkStorage();var K=null!=e?h[e]:null;if(null!=K){let t=function getCachedLockKey(e){var t=Date.now();if(e in w&&w[e].timestamp>=t-Math.min(g,t)){let{timestamp:t,...r}=w[e];return r}}(e);if(null!=t&&!p){if(u){resetAbortToken(b);let{record:e}=await registerLocalIdentity(t)||{};cleanupExternalSignalHandler(m),m=null,null!=e&&(K.lastSeq=e.lastSeq,K.passkeys=[...K.passkeys,...e.passkeys],await storeLocalIdentities())}return Object.freeze({...t,localIdentity:e})}if(delete w[e],p){if(resetAbortToken(b),({record:h[e],lockKey:t}=await registerLocalIdentity(f&&"object"==typeof f?checkLockKey(f):void 0)),cleanupExternalSignalHandler(m),m=null,null==h[e])delete h[e];else if(null!=t)return await storeLocalIdentities(),cacheLockKey(e,t),Object.freeze({...t,localIdentity:e})}else{if(u)throw new Error("Encryption/Decryption key not currently cached, unavailable for new passkey");{resetAbortToken(b);let t=a({relyingPartyID:l,mediation:"optional",allowCredentials:K.passkeys.map((({credentialID:e})=>({type:"public-key",id:e}))),signal:m.signal}),r=await n(t);if(cleanupExternalSignalHandler(m),m=null,null!=r){if(k){let e=K.passkeys.find((e=>e.credentialID==r.response.credentialID)),t=e?.publicKey;if(!(null!=t&&await o(r.response,t)))throw new Error("Auth verification failed")}return{...extractLockKey(r),localIdentity:e}}}}}else if(u){resetAbortToken(b);let{record:t,lockKey:r}=await registerLocalIdentity(f&&"object"==typeof f?checkLockKey(f):void 0)||{};if(cleanupExternalSignalHandler(m),m=null,null!=t&&null!=r)return h[e]=t,cacheLockKey(e,r),await storeLocalIdentities(),Object.freeze({...r,localIdentity:e})}else{resetAbortToken(b);let t=a({relyingPartyID:l,mediation:"optional",signal:m.signal}),r=await n(t);if(cleanupExternalSignalHandler(m),m=null,null!=r){let t=extractLockKey(r),[a]=Object.entries(h).find((([,e])=>null!=e.passkeys.find((e=>e.credentialID==r.response.credentialID))))||[];if(null!=a){if(delete w[e],K=h[e=a],k){let e=K.passkeys.find((e=>e.credentialID==r.response.credentialID)),t=e?.publicKey;if(!(null!=t&&await o(r.response,t)))throw new Error("Auth verification failed")}cacheLockKey(e,t)}else if(k)throw new Error("Auth verification requested but skipped, against unrecognized passkey (no matching local-identity)");return Object.freeze({...t,localIdentity:e})}}async function registerLocalIdentity(a=deriveLockKey()){try{let o=((h[e]||{}).lastSeq||0)+1,c=new Uint8Array(a.iv.byteLength+2),u=new DataView(new ArrayBuffer(2));u.setInt16(0,o,!1),c.set(a.iv,0),c.set(new Uint8Array(u.buffer),a.iv.byteLength);let p=t({relyingPartyID:l,relyingPartyName:y,user:{id:c,name:i,displayName:s},signal:m.signal}),f=await r(p);if(null!=f)return{record:{lastSeq:o,passkeys:[(n={seq:o,credentialID:f.response.credentialID,publicKey:f.response.publicKey},{...n,hash:computePasskeyEntryHash(n)})]},lockKey:a}}catch(e){throw new Error("Identity/Passkey registration failed",{cause:e})}var n}function extractLockKey(t){try{if(t&&t.response&&isByteArray(t.response.userID)&&t.response.userID.byteLength==d+2){let r=deriveLockKey(t.response.userID.subarray(0,d));return cacheLockKey(e,r),r}throw new Error("Passkey info missing")}catch(e){throw new Error("Chosen passkey did not provide a valid encryption/decryption key",{cause:e})}}}function resetAbortToken(e){if(m&&(cleanupExternalSignalHandler(m),m.aborted||m.abort("Passkey operation abandoned.")),m=new AbortController,null!=e)if(e.aborted)m.abort(e.reason);else{let handlerFn=()=>{cleanupExternalSignalHandler(m),m.abort(e.reason),m=e=handlerFn=null};e.addEventListener("abort",handlerFn),K.set(m,[e,handlerFn])}}function cleanupExternalSignalHandler(e){if(null!=e&&K.has(e)){let[t,r]=K.get(e);t.removeEventListener("abort",r),K.delete(e)}}function generateEntropy(e=16){return sodium.randombytes_buf(e)}function deriveLockKey(e=generateEntropy(d)){try{let t=sodium.crypto_sign_seed_keypair(e);return{keyFormatVersion:f,iv:e,publicKey:t.publicKey,privateKey:t.privateKey,encPK:sodium.crypto_sign_ed25519_pk_to_curve25519(t.publicKey),encSK:sodium.crypto_sign_ed25519_sk_to_curve25519(t.privateKey)}}catch(e){throw new Error("Encryption/decryption key derivation failed.",{cause:e})}}function checkLockKey(e){if(e&&"object"==typeof e){if(e.keyFormatVersion===f)return e;if(isByteArray(e.iv)&&e.iv.byteLength==d)return deriveLockKey(e.iv)}throw new Error("Unrecongnized lock-key")}function lockData(e,t,{outputFormat:r="base64"}={}){try{let a=dataToBuffer(e),n=sodium.crypto_box_seal(a,t.encPK);return["base64","base-64"].includes(r.toLowerCase())?c(n):n}catch(e){throw new Error("Data encryption failed.",{cause:e})}}function unlockData(e,t,{outputFormat:r="utf8",parseJSON:a=!0}={}){try{let n=sodium.crypto_box_seal_open("string"==typeof e?l(e):e,t.encPK,t.encSK);if(["utf8","utf-8"].includes(r.toLowerCase())){let e=y(n);return a?JSON.parse(e):e}return n}catch(e){throw new Error("Data decryption failed.",{cause:e})}}function signData(e,{privateKey:t}={},{outputFormat:r="base64"}={}){try{let a=sodium.crypto_sign_detached(dataToBuffer(e),t);return["base64","base-64"].includes(r.toLowerCase())?c(a):a}catch(e){throw new Error("Data signature failed.",{cause:e})}}function verifySignature(e,{publicKey:t}={},r){try{return sodium.crypto_sign_verify_detached("string"==typeof r?l(r):r,dataToBuffer(e),t)}catch(e){throw new Error("Data signature failed.",{cause:e})}}async function storeLocalIdentities(){await checkStorage();var e=Object.fromEntries(Object.entries(h).map((([e,t])=>[e,{...t,passkeys:t.passkeys.map((e=>({...e,publicKey:i(e.publicKey)})))}])));Object.keys(e).length>0?await b.set("local-identities",e):await b.remove("local-identities")}function setLockKeyCacheLifetime(e){return g=Math.max(0,Number(e)||0)}function configure({accountStorage:e,cacheLifetime:t}={}){null!=e&&function configureStorage(e){if(["idb","local-storage","session-storage","cookie","opfs","opfs-worker"].includes(e))k=e,h=b=null;else{if("object"!=typeof e||"string"!=typeof e.storageType||!["has","get","set","remove","keys","entries"].every((t=>"function"==typeof e[t])))throw new Error(`Unrecognized storage type ('${storageType}')`);b=e,k=e.storageType,h=null}}(e),null!=t&&setLockKeyCacheLifetime(t)}function dataToBuffer(e){var t=null==e?null:e instanceof ArrayBuffer?new Uint8Array(e):isByteArray(e)?e:u("object"==typeof e?JSON.stringify(e):"string"==typeof e?e:String(e));if(null==t)throw new Error("Non-empty data required.");return t}function isByteArray(e){return e instanceof Uint8Array&&e.buffer instanceof ArrayBuffer}function computePasskeyEntryHash(e){let{hash:t,...r}=e;return c(sodium.crypto_hash(JSON.stringify({...r,publicKey:i(r.publicKey)})))}async function checkStorage(){if(null==b){if(!["idb","local-storage","session-storage","cookie","opfs","opfs-worker"].includes(k))throw new Error(`Unrecognized storage type ('${k}')`);b="idb"==k?await import("@byojs/storage/idb"):"local-storage"==k?await import("@byojs/storage/local-storage"):"session-storage"==k?await import("@byojs/storage/session-storage"):"cookie"==k?await import("@byojs/storage/cookie"):"opfs"==k?await import("@byojs/storage/opfs"):"opfs-worker"==k?await import("@byojs/storage/opfs-worker"):null}null!=b&&null==h&&(h=await async function loadLocalIdentities(){return Object.fromEntries(Object.entries(await b.get("local-identities")||{}).filter((([e,t])=>"number"==typeof t.lastSeq&&Array.isArray(t.passkeys)&&t.passkeys.length>0&&t.passkeys.every((e=>"string"==typeof e.credentialID&&""!=e.credentialID&&"number"==typeof e.seq&&null!=e.publicKey&&"object"==typeof e.publicKey&&"number"==typeof e.publicKey.algoCOSE&&"string"==typeof e.publicKey.raw&&""!=e.publicKey.raw&&"string"==typeof e.publicKey.spki&&""!=e.publicKey.spki&&"string"==typeof e.hash&&""!=e.hash&&e.hash==computePasskeyEntryHash(e))))).map((([e,t])=>[e,{...t,passkeys:t.passkeys.map((e=>({...e,publicKey:s(e.publicKey)})))}])))}())} |
{ | ||
"name": "@lo-fi/local-data-lock", | ||
"description": "Protect local-first app data with encryption/decryption key secured in WebAuthn (biometric) passkeys", | ||
"version": "0.13.2", | ||
"version": "0.14.0", | ||
"exports": { | ||
@@ -24,3 +24,3 @@ ".": "./dist/bundlers/ldl.mjs", | ||
"dependencies": { | ||
"@lo-fi/client-storage": "~0.10.0", | ||
"@byojs/storage": "~0.11.0", | ||
"@lo-fi/webauthn-local-client": "~0.1000.2" | ||
@@ -27,0 +27,0 @@ }, |
@@ -410,3 +410,3 @@ # Local Data Lock | ||
By default, **Local Data Lock** will store its [passkey account metadata](#how-does-it-work) in [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API), with the **Client Storage** library's `idb` storage adapter. | ||
By default, **Local Data Lock** will store its [passkey account metadata](#how-does-it-work) in [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API), with the **Storage** library's `idb` storage adapter. | ||
@@ -425,7 +425,7 @@ However, you may wish to configure to use one of the other client storage mechanisms: | ||
The corresponding (or default) **Client Storage** adapter will be loaded dynamically (i.e., from `"@lo-fi/client-storage/*"`), at the first need for **Local Data Lock** to access or update its passkey account metadata storage. | ||
The corresponding (or default) **Storage** adapter will be loaded dynamically (i.e., from `"@byojs/storage/*"`), at the first need for **Local Data Lock** to access or update its passkey account metadata storage. | ||
### Manually specifying custom storage adapter | ||
If you want to use a custom storage adapter -- one *not* [provided by **Client Storage**](https://github.com/mylofi/client-storage?tab=readme-ov-file#client-side-storage-adapters) -- pass the storage adapter instance directly to `configure()`: | ||
If you want to use a custom storage adapter -- one *not* [provided by **Storage**](https://github.com/byojs/storage?tab=readme-ov-file#client-side-storage-adapters) -- pass the storage adapter instance directly to `configure()`: | ||
@@ -438,3 +438,3 @@ ```js | ||
**NOTE:** The adapter instance (`customStorageAdapter`) *must* conform to the [storage-adapter API as defined by **Client Storage**](https://github.com/mylofi/client-storage?tab=readme-ov-file#client-storage-api). | ||
**NOTE:** The adapter instance (`customStorageAdapter`) *must* conform to the [storage-adapter API as defined by **Storage**](https://github.com/byojs/storage?tab=readme-ov-file#storage-api). | ||
@@ -441,0 +441,0 @@ ## WebAuthn-Local-Client Utilities |
@@ -21,3 +21,3 @@ #!/usr/bin/env node | ||
const LOFI_WALC_DIST_BUNDLERS_DIR = path.join(LOFI_WALC_DIST_DIR,"bundlers"); | ||
const LOFI_CS_DIST_DIR = path.join(NODE_MODULES_DIR,"@lo-fi","client-storage","dist"); | ||
const BYOJS_STORAGE_DIST_DIR = path.join(NODE_MODULES_DIR,"@byojs","storage","dist"); | ||
@@ -28,4 +28,5 @@ const DIST_DIR = path.join(PKG_ROOT_DIR,"dist"); | ||
const DIST_AUTO_EXTERNAL_LOFI_DIR = path.join(DIST_AUTO_EXTERNAL_DIR,"@lo-fi"); | ||
const DIST_AUTO_EXTERNAL_BYOJS_DIR = path.join(DIST_AUTO_EXTERNAL_DIR,"@byojs"); | ||
const DIST_AUTO_EXTERNAL_LOFI_WALC_DIR = path.join(DIST_AUTO_EXTERNAL_LOFI_DIR,"webauthn-local-client"); | ||
const DIST_AUTO_EXTERNAL_LOFI_CS_DIR = path.join(DIST_AUTO_EXTERNAL_LOFI_DIR,"client-storage"); | ||
const DIST_AUTO_EXTERNAL_BYOJS_STORAGE_DIR = path.join(DIST_AUTO_EXTERNAL_BYOJS_DIR,"storage"); | ||
const DIST_BUNDLERS_DIR = path.join(DIST_DIR,"bundlers"); | ||
@@ -48,4 +49,5 @@ | ||
DIST_AUTO_EXTERNAL_LOFI_DIR, | ||
DIST_AUTO_EXTERNAL_BYOJS_DIR, | ||
DIST_AUTO_EXTERNAL_LOFI_WALC_DIR, | ||
DIST_AUTO_EXTERNAL_LOFI_CS_DIR, | ||
DIST_AUTO_EXTERNAL_BYOJS_STORAGE_DIR, | ||
DIST_BUNDLERS_DIR, | ||
@@ -102,5 +104,5 @@ ]) { | ||
await buildFiles( | ||
recursiveReadDir(LOFI_CS_DIST_DIR), | ||
LOFI_CS_DIST_DIR, | ||
DIST_AUTO_EXTERNAL_LOFI_CS_DIR, | ||
recursiveReadDir(BYOJS_STORAGE_DIST_DIR), | ||
BYOJS_STORAGE_DIST_DIR, | ||
DIST_AUTO_EXTERNAL_BYOJS_STORAGE_DIR, | ||
// simple copy as-is | ||
@@ -107,0 +109,0 @@ (contents,outputPath) => ({ contents, outputPath, }) |
@@ -1,4 +0,4 @@ | ||
/*! Local-Data-Lock: #FILENAME# | ||
/*! mylofi/Local-Data-Lock: #FILENAME# | ||
v#VERSION# (c) #YEAR# Kyle Simpson | ||
MIT License: http://getify.mit-license.org | ||
*/ |
@@ -800,13 +800,13 @@ import { | ||
DEFAULT_STORAGE_TYPE == "idb" ? | ||
await import("@lo-fi/client-storage/idb") : | ||
await import("@byojs/storage/idb") : | ||
DEFAULT_STORAGE_TYPE == "local-storage" ? | ||
await import("@lo-fi/client-storage/local-storage") : | ||
await import("@byojs/storage/local-storage") : | ||
DEFAULT_STORAGE_TYPE == "session-storage" ? | ||
await import("@lo-fi/client-storage/session-storage") : | ||
await import("@byojs/storage/session-storage") : | ||
DEFAULT_STORAGE_TYPE == "cookie" ? | ||
await import("@lo-fi/client-storage/cookie") : | ||
await import("@byojs/storage/cookie") : | ||
DEFAULT_STORAGE_TYPE == "opfs" ? | ||
await import("@lo-fi/client-storage/opfs") : | ||
await import("@byojs/storage/opfs") : | ||
DEFAULT_STORAGE_TYPE == "opfs-worker" ? | ||
await import("@lo-fi/client-storage/opfs-worker") : | ||
await import("@byojs/storage/opfs-worker") : | ||
@@ -813,0 +813,0 @@ // note: won't ever get here |
@@ -18,3 +18,3 @@ import { | ||
from "local-data-lock/src"; | ||
import SSStore from "@lo-fi/client-storage/session-storage"; | ||
import SSStore from "@byojs/storage/session-storage"; | ||
@@ -21,0 +21,0 @@ // simple helper util for showing a spinner |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5204
895601
+ Added@byojs/storage@~0.11.0
+ Added@byojs/storage@0.11.1(transitive)
+ Addedidb-keyval@6.2.1(transitive)
- Removed@lo-fi/client-storage@~0.10.0
- Removed@lo-fi/client-storage@0.10.2(transitive)