mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01:00 
			
		
		
		
	fix multiple UI bugs, closes #2616
This commit is contained in:
		
							parent
							
								
									1c4358086d
								
							
						
					
					
						commit
						0ca9bff61b
					
				@ -42,7 +42,9 @@ class EtapiToken extends AbstractEntity {
 | 
			
		||||
        /** @type {boolean} */
 | 
			
		||||
        this.isDeleted = !!row.isDeleted;
 | 
			
		||||
 | 
			
		||||
        this.becca.etapiTokens[this.etapiTokenId] = this;
 | 
			
		||||
        if (this.etapiTokenId) {
 | 
			
		||||
            this.becca.etapiTokens[this.etapiTokenId] = this;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init() {
 | 
			
		||||
 | 
			
		||||
@ -48,46 +48,46 @@ const TPL = `
 | 
			
		||||
export default class EtapiOptions {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        $("#options-etapi").html(TPL);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        $("#create-etapi-token").on("click", async () => {
 | 
			
		||||
            const promptDialog = await import('../../dialogs/prompt.js');
 | 
			
		||||
            const tokenName = await promptDialog.ask({
 | 
			
		||||
                title: "New ETAPI token",
 | 
			
		||||
                message: "Please enter new token's name", 
 | 
			
		||||
                defaultValue: "new token" 
 | 
			
		||||
                message: "Please enter new token's name",
 | 
			
		||||
                defaultValue: "new token"
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if (!tokenName.trim()) {
 | 
			
		||||
                alert("Token name can't be empty");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            const {token} = await server.post('etapi-tokens', {tokenName});
 | 
			
		||||
 | 
			
		||||
            await promptDialog.ask({ 
 | 
			
		||||
            const {authToken} = await server.post('etapi-tokens', {tokenName});
 | 
			
		||||
 | 
			
		||||
            await promptDialog.ask({
 | 
			
		||||
                title: "ETAPI token created",
 | 
			
		||||
                message: 'Copy the created token into clipboard. Trilium stores the token hashed and this is the last time you see it.', 
 | 
			
		||||
                defaultValue: token 
 | 
			
		||||
                message: 'Copy the created token into clipboard. Trilium stores the token hashed and this is the last time you see it.',
 | 
			
		||||
                defaultValue: authToken
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            this.refreshTokens();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.refreshTokens();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    async refreshTokens() {
 | 
			
		||||
        const $noTokensYet = $("#no-tokens-yet");
 | 
			
		||||
        const $tokensTable = $("#tokens-table");
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        const tokens = await server.get('etapi-tokens');
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        $noTokensYet.toggle(tokens.length === 0);
 | 
			
		||||
        $tokensTable.toggle(tokens.length > 0);
 | 
			
		||||
 | 
			
		||||
        const $tokensTableBody = $tokensTable.find("tbody");
 | 
			
		||||
        $tokensTableBody.empty();
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        for (const token of tokens) {
 | 
			
		||||
            $tokensTableBody.append(
 | 
			
		||||
                $("<tr>")
 | 
			
		||||
@ -112,7 +112,7 @@ export default class EtapiOptions {
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        await server.patch(`etapi-tokens/${etapiTokenId}`, {name: tokenName});
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        this.refreshTokens();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,9 +13,9 @@ let shownCb;
 | 
			
		||||
 | 
			
		||||
export function ask({ title, message, defaultValue, shown }) {
 | 
			
		||||
    shownCb = shown;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    $("#prompt-title").text(title || "Prompt");
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    $question = $("<label>")
 | 
			
		||||
        .prop("for", "prompt-dialog-answer")
 | 
			
		||||
        .text(message);
 | 
			
		||||
@ -51,7 +51,8 @@ $dialog.on("hidden.bs.modal", () => {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
$form.on('submit', () => {
 | 
			
		||||
$form.on('submit', e => {
 | 
			
		||||
    e.preventDefault();
 | 
			
		||||
    resolve($answer.val());
 | 
			
		||||
 | 
			
		||||
    $dialog.modal('hide');
 | 
			
		||||
 | 
			
		||||
@ -2,16 +2,14 @@ const etapiTokenService = require("../../services/etapi_tokens");
 | 
			
		||||
 | 
			
		||||
function getTokens() {
 | 
			
		||||
    const tokens = etapiTokenService.getTokens();
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    tokens.sort((a, b) => a.utcDateCreated < b.utcDateCreated ? -1 : 1);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return tokens;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function createToken(req) {
 | 
			
		||||
    return {
 | 
			
		||||
        authToken: etapiTokenService.createToken(req.body.tokenName)
 | 
			
		||||
    };
 | 
			
		||||
    return etapiTokenService.createToken(req.body.tokenName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function patchToken(req) {
 | 
			
		||||
@ -27,4 +25,4 @@ module.exports = {
 | 
			
		||||
    createToken,
 | 
			
		||||
    patchToken,
 | 
			
		||||
    deleteToken
 | 
			
		||||
};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ function createToken(tokenName) {
 | 
			
		||||
        name: tokenName,
 | 
			
		||||
        tokenHash
 | 
			
		||||
    }).save();
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        authToken: `${etapiToken.etapiTokenId}_${token}`
 | 
			
		||||
    };
 | 
			
		||||
@ -29,14 +29,14 @@ function parseAuthToken(auth) {
 | 
			
		||||
    if (!auth) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    const chunks = auth.split("_");
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (chunks.length === 1) {
 | 
			
		||||
        return { token: auth }; // legacy format without etapiTokenId
 | 
			
		||||
    }
 | 
			
		||||
    else if (chunks.length === 2) {
 | 
			
		||||
        return { 
 | 
			
		||||
        return {
 | 
			
		||||
            etapiTokenId: chunks[0],
 | 
			
		||||
            token: chunks[1]
 | 
			
		||||
        }
 | 
			
		||||
@ -48,20 +48,20 @@ function parseAuthToken(auth) {
 | 
			
		||||
 | 
			
		||||
function isValidAuthHeader(auth) {
 | 
			
		||||
    const parsed = parseAuthToken(auth);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (!parsed) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const authTokenHash = getTokenHash(parsed.token); 
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    const authTokenHash = getTokenHash(parsed.token);
 | 
			
		||||
 | 
			
		||||
    if (parsed.etapiTokenId) {
 | 
			
		||||
        const etapiToken = becca.getEtapiToken(parsed.etapiTokenId);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        if (!etapiToken) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        return etapiToken.tokenHash === authTokenHash;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
@ -70,31 +70,30 @@ function isValidAuthHeader(auth) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function renameToken(etapiTokenId, newName) {
 | 
			
		||||
    const etapiToken = becca.getEtapiToken(etapiTokenId);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (!etapiToken) {
 | 
			
		||||
        throw new Error(`Token ${etapiTokenId} does not exist`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    etapiToken.name = newName;
 | 
			
		||||
    etapiToken.save();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function deleteToken(etapiTokenId) {
 | 
			
		||||
    const etapiToken = becca.getEtapiToken(etapiTokenId);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (!etapiToken) {
 | 
			
		||||
        return; // ok, already deleted
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    etapiToken.isDeleted = true;
 | 
			
		||||
    etapiToken.save();
 | 
			
		||||
 | 
			
		||||
    etapiToken.markAsDeletedSimple();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
@ -104,4 +103,4 @@ module.exports = {
 | 
			
		||||
    deleteToken,
 | 
			
		||||
    parseAuthToken,
 | 
			
		||||
    isValidAuthHeader
 | 
			
		||||
};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
<div id="prompt-dialog" class="modal mx-auto" tabindex="-1" role="dialog">
 | 
			
		||||
    <div class="modal-dialog" role="document">
 | 
			
		||||
    <div class="modal-dialog modal-lg" role="document">
 | 
			
		||||
        <div class="modal-content">
 | 
			
		||||
            <form id="prompt-dialog-form">
 | 
			
		||||
                <div class="modal-header">
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user