web: add manage inbox api tokens section (#8552)

* web: add manage inbox api tokens section
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>

* web: add view inbox api key option
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>

* core: don't generate inbox api key on client
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>

* core: use separate class for inbox api keys && don't set created date on client
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
This commit is contained in:
01zulfi
2025-09-16 01:15:03 +05:00
committed by GitHub
parent 01c629f612
commit 0fa3598783
6 changed files with 543 additions and 5 deletions

View File

@@ -0,0 +1,80 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { InboxApiKey } from "../types.js";
import http from "../utils/http.js";
import constants from "../utils/constants.js";
import TokenManager from "./token-manager.js";
import Database from "./index.js";
const ENDPOINTS = {
inboxApiKeys: "/inbox/api-keys"
};
export class InboxApiKeys {
constructor(
private readonly db: Database,
private readonly tokenManager: TokenManager
) {}
async get() {
const user = await this.db.user.getUser();
if (!user) return;
const token = await this.tokenManager.getAccessToken();
if (!token) return;
const inboxApiKeys = await http.get(
`${constants.API_HOST}${ENDPOINTS.inboxApiKeys}`,
token
);
return inboxApiKeys as InboxApiKey[];
}
async revoke(key: string) {
const user = await this.db.user.getUser();
if (!user) return;
const token = await this.tokenManager.getAccessToken();
if (!token) return;
await http.delete(
`${constants.API_HOST}${ENDPOINTS.inboxApiKeys}/${key}`,
token
);
}
async create(name: string, expiryDuration: number) {
const user = await this.db.user.getUser();
if (!user) return;
const token = await this.tokenManager.getAccessToken();
if (!token) return;
const payload: Omit<InboxApiKey, "lastUsedAt" | "key" | "dateCreated"> = {
name,
expiryDate: expiryDuration === -1 ? -1 : Date.now() + expiryDuration
};
await http.post.json(
`${constants.API_HOST}${ENDPOINTS.inboxApiKeys}`,
payload,
token
);
}
}

View File

@@ -81,6 +81,7 @@ import { createTriggers, dropTriggers } from "../database/triggers.js";
import { NNMigrationProvider } from "../database/migrations.js";
import { ConfigStorage } from "../database/config.js";
import { LazyPromise } from "../utils/lazy-promise.js";
import { InboxApiKeys } from "./inbox-api-keys.js";
type EventSourceConstructor = new (
uri: string,
@@ -218,6 +219,8 @@ class Database {
vaults = new Vaults(this);
settings = new Settings(this);
inboxApiKeys = new InboxApiKeys(this, this.tokenManager);
/**
* @deprecated only kept here for migration purposes
*/

View File

@@ -582,6 +582,14 @@ export type Profile = {
profilePicture?: string;
};
export type InboxApiKey = {
name: string;
key: string;
dateCreated: number;
expiryDate: number;
lastUsedAt: number;
};
export function isDeleted(item: any): item is DeletedItem {
return !!item.deleted && item.type !== "trash";
}