mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-29 18:19:38 +02:00
Compare commits
1 Commits
master
...
vscode-ext
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
370cd08b16 |
@@ -21,6 +21,7 @@ const SCOPES = [
|
||||
"theme",
|
||||
"core",
|
||||
"clipper",
|
||||
"vscode",
|
||||
"config",
|
||||
"ci",
|
||||
"setup",
|
||||
|
||||
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": ["dbaeumer.vscode-eslint", "amodio.tsl-problem-matcher"]
|
||||
}
|
||||
33
.vscode/launch.json
vendored
Normal file
33
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/extensions/vs-code"
|
||||
],
|
||||
"outFiles": ["${workspaceFolder}/extensions/vs-code/dist/**/*.js"],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
},
|
||||
{
|
||||
"name": "Extension Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/extensions/vs-code",
|
||||
"--extensionTestsPath=${workspaceFolder}/extensions/vs-code/out/test/suite/index"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/extensions/vs-code/out/**/*.js",
|
||||
"${workspaceFolder}/extensions/vs-code/dist/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "tasks: watch-tests"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
.vscode/settings.json
vendored
12
.vscode/settings.json
vendored
@@ -1,3 +1,13 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"files.exclude": {
|
||||
"out": false, // set this to true to hide the "out" folder with the compiled JS files
|
||||
"dist": false // set this to true to hide the "dist" folder with the compiled JS files
|
||||
},
|
||||
"search.exclude": {
|
||||
"out": true, // set this to false to include "out" folder in search results
|
||||
"dist": true // set this to false to include "dist" folder in search results
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off"
|
||||
}
|
||||
|
||||
39
.vscode/tasks.json
vendored
Normal file
39
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"path": "extensions/vs-code",
|
||||
"problemMatcher": "$ts-webpack-watch",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "never",
|
||||
"group": "watchers"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch-tests",
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"path": "extensions/vs-code",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "never",
|
||||
"group": "watchers"
|
||||
},
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "tasks: watch-tests",
|
||||
"dependsOn": ["npm: watch", "npm: watch-tests"],
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
||||
357
apps/mobile/package-lock.json
generated
357
apps/mobile/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
extensions/vs-code/.vscodeignore
Normal file
13
extensions/vs-code/.vscodeignore
Normal file
@@ -0,0 +1,13 @@
|
||||
.vscode/**
|
||||
.vscode-test/**
|
||||
out/**
|
||||
node_modules/**
|
||||
src/**
|
||||
.gitignore
|
||||
.yarnrc
|
||||
webpack.config.js
|
||||
vsc-extension-quickstart.md
|
||||
**/tsconfig.json
|
||||
**/.eslintrc.json
|
||||
**/*.map
|
||||
**/*.ts
|
||||
9
extensions/vs-code/CHANGELOG.md
Normal file
9
extensions/vs-code/CHANGELOG.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to the "notesnook" extension will be documented in this file.
|
||||
|
||||
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Initial release
|
||||
71
extensions/vs-code/README.md
Normal file
71
extensions/vs-code/README.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# notesnook README
|
||||
|
||||
This is the README for your extension "notesnook". After writing up a brief description, we recommend including the following sections.
|
||||
|
||||
## Features
|
||||
|
||||
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file.
|
||||
|
||||
For example if there is an image subfolder under your extension project workspace:
|
||||
|
||||
\!\[feature X\]\(images/feature-x.png\)
|
||||
|
||||
> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow.
|
||||
|
||||
## Requirements
|
||||
|
||||
If you have any requirements or dependencies, add a section describing those and how to install and configure them.
|
||||
|
||||
## Extension Settings
|
||||
|
||||
Include if your extension adds any VS Code settings through the `contributes.configuration` extension point.
|
||||
|
||||
For example:
|
||||
|
||||
This extension contributes the following settings:
|
||||
|
||||
* `myExtension.enable`: Enable/disable this extension.
|
||||
* `myExtension.thing`: Set to `blah` to do something.
|
||||
|
||||
## Known Issues
|
||||
|
||||
Calling out known issues can help limit users opening duplicate issues against your extension.
|
||||
|
||||
## Release Notes
|
||||
|
||||
Users appreciate release notes as you update your extension.
|
||||
|
||||
### 1.0.0
|
||||
|
||||
Initial release of ...
|
||||
|
||||
### 1.0.1
|
||||
|
||||
Fixed issue #.
|
||||
|
||||
### 1.1.0
|
||||
|
||||
Added features X, Y, and Z.
|
||||
|
||||
---
|
||||
|
||||
## Following extension guidelines
|
||||
|
||||
Ensure that you've read through the extensions guidelines and follow the best practices for creating your extension.
|
||||
|
||||
* [Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines)
|
||||
|
||||
## Working with Markdown
|
||||
|
||||
You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts:
|
||||
|
||||
* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux).
|
||||
* Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux).
|
||||
* Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets.
|
||||
|
||||
## For more information
|
||||
|
||||
* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown)
|
||||
* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/)
|
||||
|
||||
**Enjoy!**
|
||||
18
extensions/vs-code/assets/logo.svg
Normal file
18
extensions/vs-code/assets/logo.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 339 339">
|
||||
<defs>
|
||||
<linearGradient xlink:href="#a" id="b" x1="188.61227" x2="193.54405" y1="165.2058" y2="216.81519" gradientTransform="rotate(5 4448 -4204) scale(2.93671)" gradientUnits="userSpaceOnUse"/>
|
||||
<linearGradient id="a">
|
||||
<stop offset="0"/>
|
||||
<stop offset="1" stop-color="#fff9f9" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient xlink:href="#a" id="c" x1="167.8" x2="270.6" y1="76.9" y2="64.2" gradientTransform="rotate(5 465 -2050) scale(1.50082)" gradientUnits="userSpaceOnUse"/>
|
||||
</defs>
|
||||
<g transform="translate(0 42)">
|
||||
<path fill="url(#b)" d="m160 205 154 42-141 44-155-42z"/>
|
||||
<path fill="url(#c)" d="M160-35v240l154 42 1-253z"/>
|
||||
<path fill="none" d="M160 205V-35m0 240L18 249m142-44 154 41"/>
|
||||
<path d="m84 109 35 54V98l21-7v91l-27 9-35-54v65l-21 6v-91z"/>
|
||||
<rect width="86.1" height="12.6" x="185" y="97" fill="#bebebe" ry="2.3" transform="skewY(15) scale(.9669 1)"/>
|
||||
<path fill="#bebebe" d="m181 169 99 26 2 3v8c0 1-1 2-2 1l-99-26-2-3v-7c0-2 1-2 2-2zm0-47 99 27 2 2v8l-2 2-99-27c-1 0-2-1-2-3v-7l2-2z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
6404
extensions/vs-code/package-lock.json
generated
Normal file
6404
extensions/vs-code/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
94
extensions/vs-code/package.json
Normal file
94
extensions/vs-code/package.json
Normal file
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"name": "@notesnook/vs-code",
|
||||
"displayName": "Notesnook",
|
||||
"description": "End-to-end encrypted notepad.",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"vscode": "^1.75.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onCommand:notesnook.helloWorld"
|
||||
],
|
||||
"main": "./dist/extension.js",
|
||||
"contributes": {
|
||||
"viewsWelcome": [
|
||||
{
|
||||
"view": "notesnook.welcome",
|
||||
"contents": "You are not logged in.\n[Login to Notesnook](command:notesnook.login)"
|
||||
}
|
||||
],
|
||||
"views": {
|
||||
"notesnook": [
|
||||
{
|
||||
"id": "notesnook.welcome",
|
||||
"name": "Not logged in",
|
||||
"when": "!notesnook.isLoggedIn"
|
||||
},
|
||||
{
|
||||
"id": "notesnook.notes",
|
||||
"name": "Notes",
|
||||
"when": "notesnook.isLoggedIn"
|
||||
},
|
||||
{
|
||||
"id": "notesnook.notebooks",
|
||||
"name": "Notebooks",
|
||||
"when": "notesnook.isLoggedIn",
|
||||
"visibility": "collapsed"
|
||||
},
|
||||
{
|
||||
"id": "notesnook.tags",
|
||||
"name": "Tags",
|
||||
"when": "notesnook.isLoggedIn",
|
||||
"visibility": "collapsed"
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewsContainers": {
|
||||
"activitybar": [
|
||||
{
|
||||
"title": "Notesnook",
|
||||
"icon": "assets/logo.svg",
|
||||
"id": "notesnook"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "npm run package",
|
||||
"compile": "webpack",
|
||||
"watch": "webpack --watch",
|
||||
"package": "webpack --mode production --devtool hidden-source-map",
|
||||
"compile-tests": "tsc -p . --outDir out",
|
||||
"watch-tests": "tsc -p . -w --outDir out",
|
||||
"pretest": "npm run compile-tests && npm run compile && npm run lint",
|
||||
"lint": "eslint src --ext ts",
|
||||
"test": "node ./out/test/runTest.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/glob": "^8.0.1",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@types/node": "16.x",
|
||||
"@types/vscode": "^1.75.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.49.0",
|
||||
"@typescript-eslint/parser": "^5.49.0",
|
||||
"@vscode/test-electron": "^2.2.2",
|
||||
"eslint": "^8.33.0",
|
||||
"glob": "^8.1.0",
|
||||
"mocha": "^10.1.0",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-cli": "^5.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@happy-dom/global-registrator": "^8.2.6",
|
||||
"@notesnook/core": "*",
|
||||
"@notesnook/crypto": "*",
|
||||
"event-source-polyfill": "^1.0.31",
|
||||
"eventsource": "^2.0.2",
|
||||
"happy-dom": "^8.2.6"
|
||||
}
|
||||
}
|
||||
36
extensions/vs-code/src/compressor.ts
Normal file
36
extensions/vs-code/src/compressor.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
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 { gzip, gunzip } from "node:zlib";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
const gzipAsync = promisify(gzip);
|
||||
const gunzipAsync = promisify(gunzip);
|
||||
|
||||
export class Compressor {
|
||||
constructor() {}
|
||||
|
||||
async compress(data: string) {
|
||||
return (await gzipAsync(data, { level: 6 })).toString("base64");
|
||||
}
|
||||
|
||||
async decompress(data: string) {
|
||||
return (await gunzipAsync(Buffer.from(data, "base64"))).toString("utf-8");
|
||||
}
|
||||
}
|
||||
132
extensions/vs-code/src/extension.ts
Normal file
132
extensions/vs-code/src/extension.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
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 "@notesnook/core/types.js";
|
||||
import EventSource from "eventsource";
|
||||
import * as vscode from "vscode";
|
||||
import { Storage } from "./storage";
|
||||
import { Compressor } from "./compressor";
|
||||
import { GlobalRegistrator } from "@happy-dom/global-registrator";
|
||||
import { randomBytes } from "crypto";
|
||||
import { EV, EVENTS } from "@notesnook/core/common.js";
|
||||
|
||||
// This method is called when your extension is activated
|
||||
// Your extension is activated the very first time the command is executed
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
GlobalRegistrator.register();
|
||||
globalThis.crypto = {
|
||||
randomBytes
|
||||
};
|
||||
|
||||
const { default: Database } = await import("@notesnook/core");
|
||||
const storage = new Storage(context.globalState, context.secrets);
|
||||
const db = new Database(storage, EventSource, null, new Compressor());
|
||||
|
||||
db.host({
|
||||
API_HOST: "https://api.notesnook.com",
|
||||
AUTH_HOST: "https://auth.streetwriters.co",
|
||||
SSE_HOST: "https://events.streetwriters.co"
|
||||
});
|
||||
console.log("KEYS", storage.getAllKeys());
|
||||
await db.init();
|
||||
|
||||
db.user.getUser().then(async (user) => {
|
||||
if (user)
|
||||
vscode.commands.executeCommand(
|
||||
"setContext",
|
||||
"notesnook.isLoggedIn",
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
db.user.fetchUser().then(async (user) => {
|
||||
if (user)
|
||||
vscode.commands.executeCommand(
|
||||
"setContext",
|
||||
"notesnook.isLoggedIn",
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
EV.subscribe(EVENTS.userLoggedIn, () => {
|
||||
vscode.window.showInformationMessage("You are logged in!");
|
||||
vscode.commands.executeCommand("setContext", "notesnook.isLoggedIn", true);
|
||||
});
|
||||
|
||||
// Use the console to output diagnostic information (console.log) and errors (console.error)
|
||||
// This line of code will only be executed once when your extension is activated
|
||||
// console.log('Congratulations, your extension "notesnook" is now active!');
|
||||
|
||||
// The command has been defined in the package.json file
|
||||
// Now provide the implementation of the command with registerCommand
|
||||
// The commandId parameter must match the command field in package.json
|
||||
const disposable = vscode.commands.registerCommand(
|
||||
"notesnook.login",
|
||||
async () => {
|
||||
const email = await vscode.window.showInputBox({
|
||||
ignoreFocusOut: true,
|
||||
title: "Your Notesnook email",
|
||||
placeHolder: "e.g. johndoe@example.com"
|
||||
});
|
||||
|
||||
try {
|
||||
const { primaryMethod } = await db.user.authenticateEmail(email);
|
||||
|
||||
const code = await vscode.window.showInputBox({
|
||||
ignoreFocusOut: true,
|
||||
title: "2-factor authentication code",
|
||||
placeHolder:
|
||||
primaryMethod === "app"
|
||||
? "Enter 6-digit 2FA code from your authenticator app."
|
||||
: primaryMethod === "sms"
|
||||
? "Enter 6-digit 2FA code you received on your phone."
|
||||
: "Enter 6-digit 2FA code you received on your email."
|
||||
});
|
||||
|
||||
if (await db.user.authenticateMultiFactorCode(code, primaryMethod)) {
|
||||
const password = await vscode.window.showInputBox({
|
||||
password: true,
|
||||
ignoreFocusOut: true,
|
||||
title: "Your Notesnook password"
|
||||
});
|
||||
|
||||
await db.user.authenticatePassword(email, password);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
||||
// This method is called when your extension is deactivated
|
||||
export function deactivate() {}
|
||||
|
||||
function showSyncIndicator() {
|
||||
const sync = vscode.window.createStatusBarItem(
|
||||
vscode.StatusBarAlignment.Left,
|
||||
0
|
||||
);
|
||||
sync.name = "Notesnook Sync Status";
|
||||
sync.text = ``;
|
||||
S;
|
||||
sync.show();
|
||||
}
|
||||
110
extensions/vs-code/src/storage.ts
Normal file
110
extensions/vs-code/src/storage.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
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 { NNCrypto } from "@notesnook/crypto";
|
||||
import { Cipher, SerializedKey } from "@notesnook/crypto/dist/src/types";
|
||||
import { Memento, SecretStorage } from "vscode";
|
||||
|
||||
const APP_SALT = "oVzKtazBo7d8sb7TBvY9jw";
|
||||
export class Storage {
|
||||
private crypto: NNCrypto;
|
||||
constructor(private storage: Memento, private secrets: SecretStorage) {
|
||||
this.crypto = new NNCrypto();
|
||||
}
|
||||
|
||||
async read(key: string) {
|
||||
return this.storage.get(key);
|
||||
}
|
||||
|
||||
async readMulti(keys: string[]) {
|
||||
const result = [];
|
||||
keys.forEach((key) => {
|
||||
result.push([key, this.storage.get(key)]);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
write(key: string, data: unknown) {
|
||||
return this.storage.update(key, data);
|
||||
}
|
||||
|
||||
remove(key: string) {
|
||||
return this.storage.update(key, undefined);
|
||||
}
|
||||
|
||||
clear() {
|
||||
return Promise.all(
|
||||
this.storage.keys().map((key) => this.storage.update(key, undefined))
|
||||
);
|
||||
}
|
||||
|
||||
getAllKeys() {
|
||||
return this.storage.keys();
|
||||
}
|
||||
|
||||
async encrypt(key: SerializedKey, plainText: string): Promise<Cipher> {
|
||||
return await this.crypto.encrypt(
|
||||
key,
|
||||
{ format: "text", data: plainText },
|
||||
"base64"
|
||||
);
|
||||
}
|
||||
|
||||
async decrypt(
|
||||
key: SerializedKey,
|
||||
cipherData: Cipher
|
||||
): Promise<string | undefined> {
|
||||
cipherData.format = "base64";
|
||||
const result = await this.crypto.decrypt(key, cipherData);
|
||||
if (typeof result.data === "string") {
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
|
||||
async deriveCryptoKey(name: string, credentials: SerializedKey) {
|
||||
const { password, salt } = credentials;
|
||||
if (!password) throw new Error("Invalid data provided to deriveCryptoKey.");
|
||||
|
||||
const keyData = await this.crypto.exportKey(password, salt);
|
||||
if (keyData.key) {
|
||||
await this.secrets.store(`${name}@_k`, keyData.key);
|
||||
} else {
|
||||
throw new Error(`Invalid key.`);
|
||||
}
|
||||
}
|
||||
|
||||
async getCryptoKey(name: string): Promise<string | undefined> {
|
||||
const key = await this.secrets.get(`${name}@_k`);
|
||||
if (!key) return;
|
||||
return key;
|
||||
}
|
||||
|
||||
async hash(password: string, email: string): Promise<string> {
|
||||
return await this.crypto.hash(password, `${APP_SALT}${email}`);
|
||||
}
|
||||
|
||||
async generateCryptoKey(
|
||||
password: string,
|
||||
salt?: string
|
||||
): Promise<SerializedKey> {
|
||||
if (!password)
|
||||
throw new Error("Invalid data provided to generateCryptoKey.");
|
||||
return await this.crypto.exportKey(password, salt);
|
||||
}
|
||||
}
|
||||
23
extensions/vs-code/src/test/runTest.ts
Normal file
23
extensions/vs-code/src/test/runTest.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import * as path from 'path';
|
||||
|
||||
import { runTests } from '@vscode/test-electron';
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
// The folder containing the Extension Manifest package.json
|
||||
// Passed to `--extensionDevelopmentPath`
|
||||
const extensionDevelopmentPath = path.resolve(__dirname, '../../');
|
||||
|
||||
// The path to test runner
|
||||
// Passed to --extensionTestsPath
|
||||
const extensionTestsPath = path.resolve(__dirname, './suite/index');
|
||||
|
||||
// Download VS Code, unzip it and run the integration test
|
||||
await runTests({ extensionDevelopmentPath, extensionTestsPath });
|
||||
} catch (err) {
|
||||
console.error('Failed to run tests', err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
15
extensions/vs-code/src/test/suite/extension.test.ts
Normal file
15
extensions/vs-code/src/test/suite/extension.test.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import * as assert from 'assert';
|
||||
|
||||
// You can import and use all API from the 'vscode' module
|
||||
// as well as import your extension to test it
|
||||
import * as vscode from 'vscode';
|
||||
// import * as myExtension from '../../extension';
|
||||
|
||||
suite('Extension Test Suite', () => {
|
||||
vscode.window.showInformationMessage('Start all tests.');
|
||||
|
||||
test('Sample test', () => {
|
||||
assert.strictEqual(-1, [1, 2, 3].indexOf(5));
|
||||
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
|
||||
});
|
||||
});
|
||||
38
extensions/vs-code/src/test/suite/index.ts
Normal file
38
extensions/vs-code/src/test/suite/index.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import * as path from 'path';
|
||||
import * as Mocha from 'mocha';
|
||||
import * as glob from 'glob';
|
||||
|
||||
export function run(): Promise<void> {
|
||||
// Create the mocha test
|
||||
const mocha = new Mocha({
|
||||
ui: 'tdd',
|
||||
color: true
|
||||
});
|
||||
|
||||
const testsRoot = path.resolve(__dirname, '..');
|
||||
|
||||
return new Promise((c, e) => {
|
||||
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
|
||||
if (err) {
|
||||
return e(err);
|
||||
}
|
||||
|
||||
// Add files to the test suite
|
||||
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
|
||||
|
||||
try {
|
||||
// Run the mocha test
|
||||
mocha.run(failures => {
|
||||
if (failures > 0) {
|
||||
e(new Error(`${failures} tests failed.`));
|
||||
} else {
|
||||
c();
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
e(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
14
extensions/vs-code/tsconfig.json
Normal file
14
extensions/vs-code/tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "ES2020",
|
||||
"lib": ["ES2020"],
|
||||
"sourceMap": true,
|
||||
"rootDir": "src",
|
||||
"maxNodeModuleJsDepth": 5
|
||||
/* Additional Checks */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
}
|
||||
}
|
||||
47
extensions/vs-code/vsc-extension-quickstart.md
Normal file
47
extensions/vs-code/vsc-extension-quickstart.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Welcome to your VS Code Extension
|
||||
|
||||
## What's in the folder
|
||||
|
||||
* This folder contains all of the files necessary for your extension.
|
||||
* `package.json` - this is the manifest file in which you declare your extension and command.
|
||||
* The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin.
|
||||
* `src/extension.ts` - this is the main file where you will provide the implementation of your command.
|
||||
* The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`.
|
||||
* We pass the function containing the implementation of the command as the second parameter to `registerCommand`.
|
||||
|
||||
## Setup
|
||||
|
||||
* install the recommended extensions (amodio.tsl-problem-matcher and dbaeumer.vscode-eslint)
|
||||
|
||||
|
||||
## Get up and running straight away
|
||||
|
||||
* Press `F5` to open a new window with your extension loaded.
|
||||
* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`.
|
||||
* Set breakpoints in your code inside `src/extension.ts` to debug your extension.
|
||||
* Find output from your extension in the debug console.
|
||||
|
||||
## Make changes
|
||||
|
||||
* You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`.
|
||||
* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes.
|
||||
|
||||
|
||||
## Explore the API
|
||||
|
||||
* You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`.
|
||||
|
||||
## Run tests
|
||||
|
||||
* Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`.
|
||||
* Press `F5` to run the tests in a new window with your extension loaded.
|
||||
* See the output of the test result in the debug console.
|
||||
* Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder.
|
||||
* The provided test runner will only consider files matching the name pattern `**.test.ts`.
|
||||
* You can create folders inside the `test` folder to structure your tests any way you want.
|
||||
|
||||
## Go further
|
||||
|
||||
* Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension).
|
||||
* [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace.
|
||||
* Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).
|
||||
48
extensions/vs-code/webpack.config.js
Normal file
48
extensions/vs-code/webpack.config.js
Normal file
@@ -0,0 +1,48 @@
|
||||
//@ts-check
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
//@ts-check
|
||||
/** @typedef {import('webpack').Configuration} WebpackConfig **/
|
||||
|
||||
/** @type WebpackConfig */
|
||||
const extensionConfig = {
|
||||
target: 'node', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
|
||||
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
|
||||
|
||||
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
|
||||
output: {
|
||||
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'extension.js',
|
||||
libraryTarget: 'commonjs2'
|
||||
},
|
||||
externals: {
|
||||
vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
|
||||
// modules added here also need to be added in the .vscodeignore file
|
||||
},
|
||||
resolve: {
|
||||
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: 'ts-loader'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
devtool: 'nosources-source-map',
|
||||
infrastructureLogging: {
|
||||
level: "log", // enables logging required for problem matchers
|
||||
},
|
||||
};
|
||||
module.exports = [ extensionConfig ];
|
||||
@@ -141,11 +141,15 @@ class UserManager {
|
||||
const user = await this.fetchUser();
|
||||
if (!user) throw new Error("Unauthorized.");
|
||||
|
||||
console.log("GOT USER", user);
|
||||
|
||||
await this._storage.deriveCryptoKey(`_uk_@${user.email}`, {
|
||||
password,
|
||||
salt: user.salt
|
||||
});
|
||||
|
||||
console.log("KEY DERIVED");
|
||||
|
||||
EV.publish(EVENTS.userLoggedIn, user);
|
||||
}
|
||||
|
||||
|
||||
9
packages/core/package-lock.json
generated
9
packages/core/package-lock.json
generated
@@ -15347,7 +15347,8 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
|
||||
"integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"jest-regex-util": {
|
||||
"version": "28.0.2",
|
||||
@@ -16021,7 +16022,8 @@
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
|
||||
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -17281,7 +17283,8 @@
|
||||
"ws": {
|
||||
"version": "7.5.9",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
|
||||
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q=="
|
||||
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
|
||||
"requires": {}
|
||||
},
|
||||
"xml-name-validator": {
|
||||
"version": "4.0.0",
|
||||
|
||||
Reference in New Issue
Block a user