@icp-sdk/auth 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/esm/client/auth-client.d.ts +177 -0
- package/dist/esm/client/auth-client.js +328 -0
- package/dist/esm/client/auth-client.js.map +1 -0
- package/dist/esm/client/db.d.ts +47 -0
- package/dist/esm/client/db.js +83 -0
- package/dist/esm/client/db.js.map +1 -0
- package/dist/esm/client/idle-manager.d.ts +81 -0
- package/dist/esm/client/idle-manager.js +81 -0
- package/dist/esm/client/idle-manager.js.map +1 -0
- package/dist/esm/client/index.d.ts +4 -0
- package/dist/esm/client/index.js +15 -0
- package/dist/esm/client/index.js.map +1 -0
- package/dist/esm/client/storage.d.ts +51 -0
- package/dist/esm/client/storage.js +83 -0
- package/dist/esm/client/storage.js.map +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/package.json +62 -0
- package/src/client/auth-client.ts +593 -0
- package/src/client/db.ts +114 -0
- package/src/client/idle-manager.ts +144 -0
- package/src/client/index.ts +10 -0
- package/src/client/storage.ts +112 -0
- package/src/index.ts +3 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { openDB } from "idb";
|
|
2
|
+
import { DB_VERSION, KEY_STORAGE_DELEGATION, KEY_STORAGE_KEY } from "./storage.js";
|
|
3
|
+
const AUTH_DB_NAME = "auth-client-db";
|
|
4
|
+
const OBJECT_STORE_NAME = "ic-keyval";
|
|
5
|
+
const _openDbStore = async (dbName = AUTH_DB_NAME, storeName = OBJECT_STORE_NAME, version) => {
|
|
6
|
+
if (localStorage?.getItem(KEY_STORAGE_DELEGATION)) {
|
|
7
|
+
localStorage.removeItem(KEY_STORAGE_DELEGATION);
|
|
8
|
+
localStorage.removeItem(KEY_STORAGE_KEY);
|
|
9
|
+
}
|
|
10
|
+
return await openDB(dbName, version, {
|
|
11
|
+
upgrade: (database) => {
|
|
12
|
+
if (database.objectStoreNames.contains(storeName)) {
|
|
13
|
+
database.clear(storeName);
|
|
14
|
+
}
|
|
15
|
+
database.createObjectStore(storeName);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
async function _getValue(db, storeName, key) {
|
|
20
|
+
return await db.get(storeName, key);
|
|
21
|
+
}
|
|
22
|
+
async function _setValue(db, storeName, key, value) {
|
|
23
|
+
return await db.put(storeName, value, key);
|
|
24
|
+
}
|
|
25
|
+
async function _removeValue(db, storeName, key) {
|
|
26
|
+
return await db.delete(storeName, key);
|
|
27
|
+
}
|
|
28
|
+
class IdbKeyVal {
|
|
29
|
+
// Do not use - instead prefer create
|
|
30
|
+
constructor(_db, _storeName) {
|
|
31
|
+
this._db = _db;
|
|
32
|
+
this._storeName = _storeName;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* @param {DBCreateOptions} options - DBCreateOptions
|
|
36
|
+
* @param {DBCreateOptions['dbName']} options.dbName name for the indexeddb database
|
|
37
|
+
* @default
|
|
38
|
+
* @param {DBCreateOptions['storeName']} options.storeName name for the indexeddb Data Store
|
|
39
|
+
* @default
|
|
40
|
+
* @param {DBCreateOptions['version']} options.version version of the database. Increment to safely upgrade
|
|
41
|
+
*/
|
|
42
|
+
static async create(options) {
|
|
43
|
+
const {
|
|
44
|
+
dbName = AUTH_DB_NAME,
|
|
45
|
+
storeName = OBJECT_STORE_NAME,
|
|
46
|
+
version = DB_VERSION
|
|
47
|
+
} = options ?? {};
|
|
48
|
+
const db = await _openDbStore(dbName, storeName, version);
|
|
49
|
+
return new IdbKeyVal(db, storeName);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Basic setter
|
|
53
|
+
* @param {IDBValidKey} key string | number | Date | BufferSource | IDBValidKey[]
|
|
54
|
+
* @param value value to set
|
|
55
|
+
* @returns void
|
|
56
|
+
*/
|
|
57
|
+
async set(key, value) {
|
|
58
|
+
return await _setValue(this._db, this._storeName, key, value);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Basic getter
|
|
62
|
+
* Pass in a type T for type safety if you know the type the value will have if it is found
|
|
63
|
+
* @param {IDBValidKey} key string | number | Date | BufferSource | IDBValidKey[]
|
|
64
|
+
* @returns `Promise<T | null>`
|
|
65
|
+
* @example
|
|
66
|
+
* await get<string>('exampleKey') -> 'exampleValue'
|
|
67
|
+
*/
|
|
68
|
+
async get(key) {
|
|
69
|
+
return await _getValue(this._db, this._storeName, key) ?? null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Remove a key
|
|
73
|
+
* @param key {@link IDBValidKey}
|
|
74
|
+
* @returns void
|
|
75
|
+
*/
|
|
76
|
+
async remove(key) {
|
|
77
|
+
return await _removeValue(this._db, this._storeName, key);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
IdbKeyVal
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sources":["../../../src/client/db.ts"],"sourcesContent":["import { type IDBPDatabase, openDB } from 'idb';\nimport { DB_VERSION, KEY_STORAGE_DELEGATION, KEY_STORAGE_KEY } from './storage.ts';\n\ntype Database = IDBPDatabase<unknown>;\ntype IDBValidKey = string | number | Date | BufferSource | IDBValidKey[];\nconst AUTH_DB_NAME = 'auth-client-db';\nconst OBJECT_STORE_NAME = 'ic-keyval';\n\nconst _openDbStore = async (\n dbName = AUTH_DB_NAME,\n storeName = OBJECT_STORE_NAME,\n version: number,\n) => {\n // Clear legacy stored delegations\n if (localStorage?.getItem(KEY_STORAGE_DELEGATION)) {\n localStorage.removeItem(KEY_STORAGE_DELEGATION);\n localStorage.removeItem(KEY_STORAGE_KEY);\n }\n return await openDB(dbName, version, {\n upgrade: (database) => {\n if (database.objectStoreNames.contains(storeName)) {\n database.clear(storeName);\n }\n database.createObjectStore(storeName);\n },\n });\n};\n\nasync function _getValue<T>(\n db: Database,\n storeName: string,\n key: IDBValidKey,\n): Promise<T | undefined> {\n return await db.get(storeName, key);\n}\n\nasync function _setValue<T>(\n db: Database,\n storeName: string,\n key: IDBValidKey,\n value: T,\n): Promise<IDBValidKey> {\n return await db.put(storeName, value, key);\n}\n\nasync function _removeValue(db: Database, storeName: string, key: IDBValidKey): Promise<void> {\n return await db.delete(storeName, key);\n}\n\nexport type DBCreateOptions = {\n dbName?: string;\n storeName?: string;\n version?: number;\n};\n\n/**\n * Simple Key Value store\n * Defaults to `'auth-client-db'` with an object store of `'ic-keyval'`\n */\nexport class IdbKeyVal {\n /**\n * @param {DBCreateOptions} options - DBCreateOptions\n * @param {DBCreateOptions['dbName']} options.dbName name for the indexeddb database\n * @default\n * @param {DBCreateOptions['storeName']} options.storeName name for the indexeddb Data Store\n * @default\n * @param {DBCreateOptions['version']} options.version version of the database. Increment to safely upgrade\n */\n public static async create(options?: DBCreateOptions): Promise<IdbKeyVal> {\n const {\n dbName = AUTH_DB_NAME,\n storeName = OBJECT_STORE_NAME,\n version = DB_VERSION,\n } = options ?? {};\n const db = await _openDbStore(dbName, storeName, version);\n return new IdbKeyVal(db, storeName);\n }\n\n // Do not use - instead prefer create\n private constructor(\n private _db: Database,\n private _storeName: string,\n ) {}\n\n /**\n * Basic setter\n * @param {IDBValidKey} key string | number | Date | BufferSource | IDBValidKey[]\n * @param value value to set\n * @returns void\n */\n public async set<T>(key: IDBValidKey, value: T) {\n return await _setValue<T>(this._db, this._storeName, key, value);\n }\n /**\n * Basic getter\n * Pass in a type T for type safety if you know the type the value will have if it is found\n * @param {IDBValidKey} key string | number | Date | BufferSource | IDBValidKey[]\n * @returns `Promise<T | null>`\n * @example\n * await get<string>('exampleKey') -> 'exampleValue'\n */\n public async get<T>(key: IDBValidKey): Promise<T | null> {\n return (await _getValue<T>(this._db, this._storeName, key)) ?? null;\n }\n\n /**\n * Remove a key\n * @param key {@link IDBValidKey}\n * @returns void\n */\n public async remove(key: IDBValidKey) {\n return await _removeValue(this._db, this._storeName, key);\n }\n}\n"],"names":[],"mappings":";;AAKA,MAAM,eAAe;AACrB,MAAM,oBAAoB;AAE1B,MAAM,eAAe,OACnB,SAAS,cACT,YAAY,mBACZ,YACG;AAEH,MAAI,cAAc,QAAQ,sBAAsB,GAAG;AACjD,iBAAa,WAAW,sBAAsB;AAC9C,iBAAa,WAAW,eAAe;AAAA,EACzC;AACA,SAAO,MAAM,OAAO,QAAQ,SAAS;AAAA,IACnC,SAAS,CAAC,aAAa;AACrB,UAAI,SAAS,iBAAiB,SAAS,SAAS,GAAG;AACjD,iBAAS,MAAM,SAAS;AAAA,MAC1B;AACA,eAAS,kBAAkB,SAAS;AAAA,IACtC;AAAA,EAAA,CACD;AACH;AAEA,eAAe,UACb,IACA,WACA,KACwB;AACxB,SAAO,MAAM,GAAG,IAAI,WAAW,GAAG;AACpC;AAEA,eAAe,UACb,IACA,WACA,KACA,OACsB;AACtB,SAAO,MAAM,GAAG,IAAI,WAAW,OAAO,GAAG;AAC3C;AAEA,eAAe,aAAa,IAAc,WAAmB,KAAiC;AAC5F,SAAO,MAAM,GAAG,OAAO,WAAW,GAAG;AACvC;AAYO,MAAM,UAAU;AAAA;AAAA,EAoBb,YACE,KACA,YACR;AAFQ,SAAA,MAAA;AACA,SAAA,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAdH,aAAoB,OAAO,SAA+C;AACxE,UAAM;AAAA,MACJ,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,UAAU;AAAA,IAAA,IACR,WAAW,CAAA;AACf,UAAM,KAAK,MAAM,aAAa,QAAQ,WAAW,OAAO;AACxD,WAAO,IAAI,UAAU,IAAI,SAAS;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAa,IAAO,KAAkB,OAAU;AAC9C,WAAO,MAAM,UAAa,KAAK,KAAK,KAAK,YAAY,KAAK,KAAK;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAa,IAAO,KAAqC;AACvD,WAAQ,MAAM,UAAa,KAAK,KAAK,KAAK,YAAY,GAAG,KAAM;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,OAAO,KAAkB;AACpC,WAAO,MAAM,aAAa,KAAK,KAAK,KAAK,YAAY,GAAG;AAAA,EAC1D;AACF;"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
type IdleCB = () => unknown;
|
|
2
|
+
export type IdleManagerOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* Callback after the user has gone idle
|
|
5
|
+
*/
|
|
6
|
+
onIdle?: IdleCB;
|
|
7
|
+
/**
|
|
8
|
+
* timeout in ms
|
|
9
|
+
* @default 30 minutes [600_000]
|
|
10
|
+
*/
|
|
11
|
+
idleTimeout?: number;
|
|
12
|
+
/**
|
|
13
|
+
* capture scroll events
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
captureScroll?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* scroll debounce time in ms
|
|
19
|
+
* @default 100
|
|
20
|
+
*/
|
|
21
|
+
scrollDebounce?: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Detects if the user has been idle for a duration of `idleTimeout` ms, and calls `onIdle` and registered callbacks.
|
|
25
|
+
* By default, the IdleManager will log a user out after 10 minutes of inactivity.
|
|
26
|
+
* To override these defaults, you can pass an `onIdle` callback, or configure a custom `idleTimeout` in milliseconds
|
|
27
|
+
*/
|
|
28
|
+
export declare class IdleManager {
|
|
29
|
+
callbacks: IdleCB[];
|
|
30
|
+
idleTimeout: IdleManagerOptions['idleTimeout'];
|
|
31
|
+
timeoutID?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Creates an {@link IdleManager}
|
|
34
|
+
* @param {IdleManagerOptions} options Optional configuration
|
|
35
|
+
* @see {@link IdleManagerOptions}
|
|
36
|
+
* @param options.onIdle Callback once user has been idle. Use to prompt for fresh login, and use `Actor.agentOf(your_actor).invalidateIdentity()` to protect the user
|
|
37
|
+
* @param options.idleTimeout timeout in ms
|
|
38
|
+
* @param options.captureScroll capture scroll events
|
|
39
|
+
* @param options.scrollDebounce scroll debounce time in ms
|
|
40
|
+
*/
|
|
41
|
+
static create(options?: {
|
|
42
|
+
/**
|
|
43
|
+
* Callback after the user has gone idle
|
|
44
|
+
* @see {@link IdleCB}
|
|
45
|
+
*/
|
|
46
|
+
onIdle?: () => unknown;
|
|
47
|
+
/**
|
|
48
|
+
* timeout in ms
|
|
49
|
+
* @default 10 minutes [600_000]
|
|
50
|
+
*/
|
|
51
|
+
idleTimeout?: number;
|
|
52
|
+
/**
|
|
53
|
+
* capture scroll events
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
captureScroll?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* scroll debounce time in ms
|
|
59
|
+
* @default 100
|
|
60
|
+
*/
|
|
61
|
+
scrollDebounce?: number;
|
|
62
|
+
}): IdleManager;
|
|
63
|
+
/**
|
|
64
|
+
* @protected
|
|
65
|
+
* @param options {@link IdleManagerOptions}
|
|
66
|
+
*/
|
|
67
|
+
protected constructor(options?: IdleManagerOptions);
|
|
68
|
+
/**
|
|
69
|
+
* @param {IdleCB} callback function to be called when user goes idle
|
|
70
|
+
*/
|
|
71
|
+
registerCallback(callback: IdleCB): void;
|
|
72
|
+
/**
|
|
73
|
+
* Cleans up the idle manager and its listeners
|
|
74
|
+
*/
|
|
75
|
+
exit(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Resets the timeouts during cleanup
|
|
78
|
+
*/
|
|
79
|
+
_resetTimer(): void;
|
|
80
|
+
}
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const events = ["mousedown", "mousemove", "keydown", "touchstart", "wheel"];
|
|
2
|
+
class IdleManager {
|
|
3
|
+
callbacks = [];
|
|
4
|
+
idleTimeout = 10 * 60 * 1e3;
|
|
5
|
+
timeoutID = void 0;
|
|
6
|
+
/**
|
|
7
|
+
* Creates an {@link IdleManager}
|
|
8
|
+
* @param {IdleManagerOptions} options Optional configuration
|
|
9
|
+
* @see {@link IdleManagerOptions}
|
|
10
|
+
* @param options.onIdle Callback once user has been idle. Use to prompt for fresh login, and use `Actor.agentOf(your_actor).invalidateIdentity()` to protect the user
|
|
11
|
+
* @param options.idleTimeout timeout in ms
|
|
12
|
+
* @param options.captureScroll capture scroll events
|
|
13
|
+
* @param options.scrollDebounce scroll debounce time in ms
|
|
14
|
+
*/
|
|
15
|
+
static create(options = {}) {
|
|
16
|
+
return new IdleManager(options);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @protected
|
|
20
|
+
* @param options {@link IdleManagerOptions}
|
|
21
|
+
*/
|
|
22
|
+
constructor(options = {}) {
|
|
23
|
+
const { onIdle, idleTimeout = 10 * 60 * 1e3 } = options || {};
|
|
24
|
+
this.callbacks = onIdle ? [onIdle] : [];
|
|
25
|
+
this.idleTimeout = idleTimeout;
|
|
26
|
+
const _resetTimer = this._resetTimer.bind(this);
|
|
27
|
+
window.addEventListener("load", _resetTimer, true);
|
|
28
|
+
events.forEach((name) => {
|
|
29
|
+
document.addEventListener(name, _resetTimer, true);
|
|
30
|
+
});
|
|
31
|
+
const debounce = (func, wait) => {
|
|
32
|
+
let timeout;
|
|
33
|
+
return (...args) => {
|
|
34
|
+
const context = this;
|
|
35
|
+
const later = () => {
|
|
36
|
+
timeout = void 0;
|
|
37
|
+
func.apply(context, args);
|
|
38
|
+
};
|
|
39
|
+
clearTimeout(timeout);
|
|
40
|
+
timeout = window.setTimeout(later, wait);
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
if (options?.captureScroll) {
|
|
44
|
+
const scroll = debounce(_resetTimer, options?.scrollDebounce ?? 100);
|
|
45
|
+
window.addEventListener("scroll", scroll, true);
|
|
46
|
+
}
|
|
47
|
+
_resetTimer();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* @param {IdleCB} callback function to be called when user goes idle
|
|
51
|
+
*/
|
|
52
|
+
registerCallback(callback) {
|
|
53
|
+
this.callbacks.push(callback);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Cleans up the idle manager and its listeners
|
|
57
|
+
*/
|
|
58
|
+
exit() {
|
|
59
|
+
clearTimeout(this.timeoutID);
|
|
60
|
+
window.removeEventListener("load", this._resetTimer, true);
|
|
61
|
+
const _resetTimer = this._resetTimer.bind(this);
|
|
62
|
+
events.forEach((name) => {
|
|
63
|
+
document.removeEventListener(name, _resetTimer, true);
|
|
64
|
+
});
|
|
65
|
+
this.callbacks.forEach((cb) => {
|
|
66
|
+
cb();
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Resets the timeouts during cleanup
|
|
71
|
+
*/
|
|
72
|
+
_resetTimer() {
|
|
73
|
+
const exit = this.exit.bind(this);
|
|
74
|
+
window.clearTimeout(this.timeoutID);
|
|
75
|
+
this.timeoutID = window.setTimeout(exit, this.idleTimeout);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
IdleManager
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=idle-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idle-manager.js","sources":["../../../src/client/idle-manager.ts"],"sourcesContent":["type IdleCB = () => unknown;\n\nexport type IdleManagerOptions = {\n /**\n * Callback after the user has gone idle\n */\n onIdle?: IdleCB;\n /**\n * timeout in ms\n * @default 30 minutes [600_000]\n */\n idleTimeout?: number;\n /**\n * capture scroll events\n * @default false\n */\n captureScroll?: boolean;\n /**\n * scroll debounce time in ms\n * @default 100\n */\n scrollDebounce?: number;\n};\n\nconst events = ['mousedown', 'mousemove', 'keydown', 'touchstart', 'wheel'];\n\n/**\n * Detects if the user has been idle for a duration of `idleTimeout` ms, and calls `onIdle` and registered callbacks.\n * By default, the IdleManager will log a user out after 10 minutes of inactivity.\n * To override these defaults, you can pass an `onIdle` callback, or configure a custom `idleTimeout` in milliseconds\n */\nexport class IdleManager {\n callbacks: IdleCB[] = [];\n idleTimeout: IdleManagerOptions['idleTimeout'] = 10 * 60 * 1000;\n timeoutID?: number = undefined;\n\n /**\n * Creates an {@link IdleManager}\n * @param {IdleManagerOptions} options Optional configuration\n * @see {@link IdleManagerOptions}\n * @param options.onIdle Callback once user has been idle. Use to prompt for fresh login, and use `Actor.agentOf(your_actor).invalidateIdentity()` to protect the user\n * @param options.idleTimeout timeout in ms\n * @param options.captureScroll capture scroll events\n * @param options.scrollDebounce scroll debounce time in ms\n */\n public static create(\n options: {\n /**\n * Callback after the user has gone idle\n * @see {@link IdleCB}\n */\n onIdle?: () => unknown;\n /**\n * timeout in ms\n * @default 10 minutes [600_000]\n */\n idleTimeout?: number;\n /**\n * capture scroll events\n * @default false\n */\n captureScroll?: boolean;\n /**\n * scroll debounce time in ms\n * @default 100\n */\n scrollDebounce?: number;\n } = {},\n ): IdleManager {\n return new IdleManager(options);\n }\n\n /**\n * @protected\n * @param options {@link IdleManagerOptions}\n */\n protected constructor(options: IdleManagerOptions = {}) {\n const { onIdle, idleTimeout = 10 * 60 * 1000 } = options || {};\n\n this.callbacks = onIdle ? [onIdle] : [];\n this.idleTimeout = idleTimeout;\n\n const _resetTimer = this._resetTimer.bind(this);\n\n window.addEventListener('load', _resetTimer, true);\n\n events.forEach((name) => {\n document.addEventListener(name, _resetTimer, true);\n });\n\n const debounce = (func: (...args: unknown[]) => void, wait: number) => {\n let timeout: number | undefined;\n return (...args: unknown[]) => {\n const context = this;\n const later = () => {\n timeout = undefined;\n func.apply(context, args);\n };\n clearTimeout(timeout);\n timeout = window.setTimeout(later, wait);\n };\n };\n\n if (options?.captureScroll) {\n // debounce scroll events\n const scroll = debounce(_resetTimer, options?.scrollDebounce ?? 100);\n window.addEventListener('scroll', scroll, true);\n }\n\n _resetTimer();\n }\n\n /**\n * @param {IdleCB} callback function to be called when user goes idle\n */\n public registerCallback(callback: IdleCB): void {\n this.callbacks.push(callback);\n }\n\n /**\n * Cleans up the idle manager and its listeners\n */\n public exit(): void {\n clearTimeout(this.timeoutID);\n window.removeEventListener('load', this._resetTimer, true);\n\n const _resetTimer = this._resetTimer.bind(this);\n events.forEach((name) => {\n document.removeEventListener(name, _resetTimer, true);\n });\n this.callbacks.forEach((cb) => {\n cb();\n });\n }\n\n /**\n * Resets the timeouts during cleanup\n */\n _resetTimer(): void {\n const exit = this.exit.bind(this);\n window.clearTimeout(this.timeoutID);\n this.timeoutID = window.setTimeout(exit, this.idleTimeout);\n }\n}\n"],"names":[],"mappings":"AAwBA,MAAM,SAAS,CAAC,aAAa,aAAa,WAAW,cAAc,OAAO;AAOnE,MAAM,YAAY;AAAA,EACvB,YAAsB,CAAA;AAAA,EACtB,cAAiD,KAAK,KAAK;AAAA,EAC3D,YAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWrB,OAAc,OACZ,UAqBI,IACS;AACb,WAAO,IAAI,YAAY,OAAO;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,YAAY,UAA8B,IAAI;AACtD,UAAM,EAAE,QAAQ,cAAc,KAAK,KAAK,IAAA,IAAS,WAAW,CAAA;AAE5D,SAAK,YAAY,SAAS,CAAC,MAAM,IAAI,CAAA;AACrC,SAAK,cAAc;AAEnB,UAAM,cAAc,KAAK,YAAY,KAAK,IAAI;AAE9C,WAAO,iBAAiB,QAAQ,aAAa,IAAI;AAEjD,WAAO,QAAQ,CAAC,SAAS;AACvB,eAAS,iBAAiB,MAAM,aAAa,IAAI;AAAA,IACnD,CAAC;AAED,UAAM,WAAW,CAAC,MAAoC,SAAiB;AACrE,UAAI;AACJ,aAAO,IAAI,SAAoB;AAC7B,cAAM,UAAU;AAChB,cAAM,QAAQ,MAAM;AAClB,oBAAU;AACV,eAAK,MAAM,SAAS,IAAI;AAAA,QAC1B;AACA,qBAAa,OAAO;AACpB,kBAAU,OAAO,WAAW,OAAO,IAAI;AAAA,MACzC;AAAA,IACF;AAEA,QAAI,SAAS,eAAe;AAE1B,YAAM,SAAS,SAAS,aAAa,SAAS,kBAAkB,GAAG;AACnE,aAAO,iBAAiB,UAAU,QAAQ,IAAI;AAAA,IAChD;AAEA,gBAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,iBAAiB,UAAwB;AAC9C,SAAK,UAAU,KAAK,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKO,OAAa;AAClB,iBAAa,KAAK,SAAS;AAC3B,WAAO,oBAAoB,QAAQ,KAAK,aAAa,IAAI;AAEzD,UAAM,cAAc,KAAK,YAAY,KAAK,IAAI;AAC9C,WAAO,QAAQ,CAAC,SAAS;AACvB,eAAS,oBAAoB,MAAM,aAAa,IAAI;AAAA,IACtD,CAAC;AACD,SAAK,UAAU,QAAQ,CAAC,OAAO;AAC7B,SAAA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,cAAoB;AAClB,UAAM,OAAO,KAAK,KAAK,KAAK,IAAI;AAChC,WAAO,aAAa,KAAK,SAAS;AAClC,SAAK,YAAY,OAAO,WAAW,MAAM,KAAK,WAAW;AAAA,EAC3D;AACF;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AuthClient, ERROR_USER_INTERRUPT } from "./auth-client.js";
|
|
2
|
+
import { IdbKeyVal } from "./db.js";
|
|
3
|
+
import { IdleManager } from "./idle-manager.js";
|
|
4
|
+
import { IdbStorage, KEY_STORAGE_DELEGATION, KEY_STORAGE_KEY, LocalStorage } from "./storage.js";
|
|
5
|
+
export {
|
|
6
|
+
AuthClient,
|
|
7
|
+
ERROR_USER_INTERRUPT,
|
|
8
|
+
IdbKeyVal,
|
|
9
|
+
IdbStorage,
|
|
10
|
+
IdleManager,
|
|
11
|
+
KEY_STORAGE_DELEGATION,
|
|
12
|
+
KEY_STORAGE_KEY,
|
|
13
|
+
LocalStorage
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { DBCreateOptions, IdbKeyVal } from './db.ts';
|
|
2
|
+
export declare const KEY_STORAGE_KEY = "identity";
|
|
3
|
+
export declare const KEY_STORAGE_DELEGATION = "delegation";
|
|
4
|
+
export declare const KEY_VECTOR = "iv";
|
|
5
|
+
export declare const DB_VERSION = 1;
|
|
6
|
+
export type StoredKey = string | CryptoKeyPair;
|
|
7
|
+
/**
|
|
8
|
+
* Interface for persisting user authentication data
|
|
9
|
+
*/
|
|
10
|
+
export interface AuthClientStorage {
|
|
11
|
+
get(key: string): Promise<StoredKey | null>;
|
|
12
|
+
set(key: string, value: StoredKey): Promise<void>;
|
|
13
|
+
remove(key: string): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Legacy implementation of AuthClientStorage, for use where IndexedDb is not available
|
|
17
|
+
*/
|
|
18
|
+
export declare class LocalStorage implements AuthClientStorage {
|
|
19
|
+
readonly prefix: string;
|
|
20
|
+
private readonly _localStorage?;
|
|
21
|
+
constructor(prefix?: string, _localStorage?: Storage | undefined);
|
|
22
|
+
get(key: string): Promise<string | null>;
|
|
23
|
+
set(key: string, value: string): Promise<void>;
|
|
24
|
+
remove(key: string): Promise<void>;
|
|
25
|
+
private _getLocalStorage;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* IdbStorage is an interface for simple storage of string key-value pairs built on {@link IdbKeyVal}
|
|
29
|
+
*
|
|
30
|
+
* It replaces {@link LocalStorage}
|
|
31
|
+
* @see implements {@link AuthClientStorage}
|
|
32
|
+
*/
|
|
33
|
+
export declare class IdbStorage implements AuthClientStorage {
|
|
34
|
+
#private;
|
|
35
|
+
/**
|
|
36
|
+
* @param options - DBCreateOptions
|
|
37
|
+
* @param options.dbName - name for the indexeddb database
|
|
38
|
+
* @param options.storeName - name for the indexeddb Data Store
|
|
39
|
+
* @param options.version - version of the database. Increment to safely upgrade
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const storage = new IdbStorage({ dbName: 'my-db', storeName: 'my-store', version: 2 });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
constructor(options?: DBCreateOptions);
|
|
46
|
+
private initializedDb;
|
|
47
|
+
get _db(): Promise<IdbKeyVal>;
|
|
48
|
+
get<T = string>(key: string): Promise<T | null>;
|
|
49
|
+
set<T = string>(key: string, value: T): Promise<void>;
|
|
50
|
+
remove(key: string): Promise<void>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { IdbKeyVal } from "./db.js";
|
|
2
|
+
const KEY_STORAGE_KEY = "identity";
|
|
3
|
+
const KEY_STORAGE_DELEGATION = "delegation";
|
|
4
|
+
const KEY_VECTOR = "iv";
|
|
5
|
+
const DB_VERSION = 1;
|
|
6
|
+
class LocalStorage {
|
|
7
|
+
constructor(prefix = "ic-", _localStorage) {
|
|
8
|
+
this.prefix = prefix;
|
|
9
|
+
this._localStorage = _localStorage;
|
|
10
|
+
}
|
|
11
|
+
get(key) {
|
|
12
|
+
return Promise.resolve(this._getLocalStorage().getItem(this.prefix + key));
|
|
13
|
+
}
|
|
14
|
+
set(key, value) {
|
|
15
|
+
this._getLocalStorage().setItem(this.prefix + key, value);
|
|
16
|
+
return Promise.resolve();
|
|
17
|
+
}
|
|
18
|
+
remove(key) {
|
|
19
|
+
this._getLocalStorage().removeItem(this.prefix + key);
|
|
20
|
+
return Promise.resolve();
|
|
21
|
+
}
|
|
22
|
+
_getLocalStorage() {
|
|
23
|
+
if (this._localStorage) {
|
|
24
|
+
return this._localStorage;
|
|
25
|
+
}
|
|
26
|
+
const ls = globalThis.localStorage;
|
|
27
|
+
if (!ls) {
|
|
28
|
+
throw new Error("Could not find local storage.");
|
|
29
|
+
}
|
|
30
|
+
return ls;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
class IdbStorage {
|
|
34
|
+
#options;
|
|
35
|
+
/**
|
|
36
|
+
* @param options - DBCreateOptions
|
|
37
|
+
* @param options.dbName - name for the indexeddb database
|
|
38
|
+
* @param options.storeName - name for the indexeddb Data Store
|
|
39
|
+
* @param options.version - version of the database. Increment to safely upgrade
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const storage = new IdbStorage({ dbName: 'my-db', storeName: 'my-store', version: 2 });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
constructor(options) {
|
|
46
|
+
this.#options = options ?? {};
|
|
47
|
+
}
|
|
48
|
+
// Initializes a KeyVal on first request
|
|
49
|
+
initializedDb;
|
|
50
|
+
get _db() {
|
|
51
|
+
return new Promise((resolve) => {
|
|
52
|
+
if (this.initializedDb) {
|
|
53
|
+
resolve(this.initializedDb);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
IdbKeyVal.create(this.#options).then((db) => {
|
|
57
|
+
this.initializedDb = db;
|
|
58
|
+
resolve(db);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async get(key) {
|
|
63
|
+
const db = await this._db;
|
|
64
|
+
return await db.get(key);
|
|
65
|
+
}
|
|
66
|
+
async set(key, value) {
|
|
67
|
+
const db = await this._db;
|
|
68
|
+
await db.set(key, value);
|
|
69
|
+
}
|
|
70
|
+
async remove(key) {
|
|
71
|
+
const db = await this._db;
|
|
72
|
+
await db.remove(key);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
DB_VERSION,
|
|
77
|
+
IdbStorage,
|
|
78
|
+
KEY_STORAGE_DELEGATION,
|
|
79
|
+
KEY_STORAGE_KEY,
|
|
80
|
+
KEY_VECTOR,
|
|
81
|
+
LocalStorage
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sources":["../../../src/client/storage.ts"],"sourcesContent":["import { type DBCreateOptions, IdbKeyVal } from './db.ts';\n\nexport const KEY_STORAGE_KEY = 'identity';\nexport const KEY_STORAGE_DELEGATION = 'delegation';\nexport const KEY_VECTOR = 'iv';\n// Increment if any fields are modified\nexport const DB_VERSION = 1;\n\nexport type StoredKey = string | CryptoKeyPair;\n\n/**\n * Interface for persisting user authentication data\n */\nexport interface AuthClientStorage {\n get(key: string): Promise<StoredKey | null>;\n\n set(key: string, value: StoredKey): Promise<void>;\n\n remove(key: string): Promise<void>;\n}\n\n/**\n * Legacy implementation of AuthClientStorage, for use where IndexedDb is not available\n */\nexport class LocalStorage implements AuthClientStorage {\n constructor(\n public readonly prefix = 'ic-',\n private readonly _localStorage?: Storage,\n ) {}\n\n public get(key: string): Promise<string | null> {\n return Promise.resolve(this._getLocalStorage().getItem(this.prefix + key));\n }\n\n public set(key: string, value: string): Promise<void> {\n this._getLocalStorage().setItem(this.prefix + key, value);\n return Promise.resolve();\n }\n\n public remove(key: string): Promise<void> {\n this._getLocalStorage().removeItem(this.prefix + key);\n return Promise.resolve();\n }\n\n private _getLocalStorage() {\n if (this._localStorage) {\n return this._localStorage;\n }\n\n const ls = globalThis.localStorage;\n if (!ls) {\n throw new Error('Could not find local storage.');\n }\n\n return ls;\n }\n}\n\n/**\n * IdbStorage is an interface for simple storage of string key-value pairs built on {@link IdbKeyVal}\n *\n * It replaces {@link LocalStorage}\n * @see implements {@link AuthClientStorage}\n */\nexport class IdbStorage implements AuthClientStorage {\n #options: DBCreateOptions;\n\n /**\n * @param options - DBCreateOptions\n * @param options.dbName - name for the indexeddb database\n * @param options.storeName - name for the indexeddb Data Store\n * @param options.version - version of the database. Increment to safely upgrade\n * @example\n * ```ts\n * const storage = new IdbStorage({ dbName: 'my-db', storeName: 'my-store', version: 2 });\n * ```\n */\n constructor(options?: DBCreateOptions) {\n this.#options = options ?? {};\n }\n\n // Initializes a KeyVal on first request\n private initializedDb: IdbKeyVal | undefined;\n get _db(): Promise<IdbKeyVal> {\n return new Promise((resolve) => {\n if (this.initializedDb) {\n resolve(this.initializedDb);\n return;\n }\n IdbKeyVal.create(this.#options).then((db) => {\n this.initializedDb = db;\n resolve(db);\n });\n });\n }\n\n public async get<T = string>(key: string): Promise<T | null> {\n const db = await this._db;\n return await db.get<T>(key);\n // return (await db.get<string>(key)) ?? null;\n }\n\n public async set<T = string>(key: string, value: T): Promise<void> {\n const db = await this._db;\n await db.set(key, value);\n }\n\n public async remove(key: string): Promise<void> {\n const db = await this._db;\n await db.remove(key);\n }\n}\n"],"names":[],"mappings":";AAEO,MAAM,kBAAkB;AACxB,MAAM,yBAAyB;AAC/B,MAAM,aAAa;AAEnB,MAAM,aAAa;AAkBnB,MAAM,aAA0C;AAAA,EACrD,YACkB,SAAS,OACR,eACjB;AAFgB,SAAA,SAAA;AACC,SAAA,gBAAA;AAAA,EAChB;AAAA,EAEI,IAAI,KAAqC;AAC9C,WAAO,QAAQ,QAAQ,KAAK,iBAAA,EAAmB,QAAQ,KAAK,SAAS,GAAG,CAAC;AAAA,EAC3E;AAAA,EAEO,IAAI,KAAa,OAA8B;AACpD,SAAK,mBAAmB,QAAQ,KAAK,SAAS,KAAK,KAAK;AACxD,WAAO,QAAQ,QAAA;AAAA,EACjB;AAAA,EAEO,OAAO,KAA4B;AACxC,SAAK,iBAAA,EAAmB,WAAW,KAAK,SAAS,GAAG;AACpD,WAAO,QAAQ,QAAA;AAAA,EACjB;AAAA,EAEQ,mBAAmB;AACzB,QAAI,KAAK,eAAe;AACtB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,KAAK,WAAW;AACtB,QAAI,CAAC,IAAI;AACP,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AAEA,WAAO;AAAA,EACT;AACF;AAQO,MAAM,WAAwC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAY,SAA2B;AACrC,SAAK,WAAW,WAAW,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGQ;AAAA,EACR,IAAI,MAA0B;AAC5B,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAI,KAAK,eAAe;AACtB,gBAAQ,KAAK,aAAa;AAC1B;AAAA,MACF;AACA,gBAAU,OAAO,KAAK,QAAQ,EAAE,KAAK,CAAC,OAAO;AAC3C,aAAK,gBAAgB;AACrB,gBAAQ,EAAE;AAAA,MACZ,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,IAAgB,KAAgC;AAC3D,UAAM,KAAK,MAAM,KAAK;AACtB,WAAO,MAAM,GAAG,IAAO,GAAG;AAAA,EAE5B;AAAA,EAEA,MAAa,IAAgB,KAAa,OAAyB;AACjE,UAAM,KAAK,MAAM,KAAK;AACtB,UAAM,GAAG,IAAI,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,MAAa,OAAO,KAA4B;AAC9C,UAAM,KAAK,MAAM,KAAK;AACtB,UAAM,GAAG,OAAO,GAAG;AAAA,EACrB;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["throw new Error(\n 'There are no exports in the root module of this package. Import from submodules instead. Use intellisense or the docs to find the available submodules.',\n);\n"],"names":[],"mappings":"AAAA,MAAM,IAAI;AAAA,EACR;AACF;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@icp-sdk/auth",
|
|
3
|
+
"version": "4.0.0-beta.1",
|
|
4
|
+
"author": "DFINITY Stiftung <sdk@dfinity.org>",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"description": "Authentication library for Internet Computer web apps",
|
|
7
|
+
"homepage": "https://js.icp.build/auth/",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/dfinity/icp-js-auth.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/dfinity/icp-js-auth/issues"
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"type": "module",
|
|
17
|
+
"types": "./dist/esm/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/esm/index.d.ts",
|
|
21
|
+
"import": "./dist/esm/index.js",
|
|
22
|
+
"default": "./dist/esm/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./client": {
|
|
25
|
+
"types": "./dist/esm/client/index.d.ts",
|
|
26
|
+
"import": "./dist/esm/client/index.js",
|
|
27
|
+
"default": "./dist/esm/client/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"src",
|
|
34
|
+
"package.json",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@biomejs/biome": "^2.2.4",
|
|
40
|
+
"@icp-sdk/core": "^4.0.4",
|
|
41
|
+
"@tanstack/config": "^0.20.2",
|
|
42
|
+
"fake-indexeddb": "^6.2.2",
|
|
43
|
+
"jsdom": "^27.0.0",
|
|
44
|
+
"publint": "^0.3.13",
|
|
45
|
+
"typescript": "^5.9.2",
|
|
46
|
+
"vite": "^7.1.7",
|
|
47
|
+
"vitest": "3.2.4"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@icp-sdk/core": "^4.0.4"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"idb": "^8.0.3"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "vite build && pnpm lint:package",
|
|
57
|
+
"test": "vitest",
|
|
58
|
+
"codestyle:check": "biome check",
|
|
59
|
+
"codestyle:fix": "biome check --write",
|
|
60
|
+
"lint:package": "publint --strict"
|
|
61
|
+
}
|
|
62
|
+
}
|