New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

scrt-link-core

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scrt-link-core - npm Package Compare versions

Comparing version 0.2.2 to 0.2.3

.prettierrc

11

.eslintrc.js
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
],
};
plugins: ['@typescript-eslint'],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
}

@@ -8,2 +8,9 @@ # Change Log

## [0.2.3] - 2022-02-02
### Changed
- Support file secret type
- Add prettier, format code base
## [0.2.2] - 2021-11-25

@@ -10,0 +17,0 @@

@@ -5,3 +5,3 @@ /**

*/
import { CreateSecret, RetrieveSecret } from "./main";
import { CreateSecret, RetrieveSecret } from './main';
declare global {

@@ -8,0 +8,0 @@ interface Window {

@@ -6,3 +6,3 @@ "use strict";

exports.encryptionKeyLength = 24; // 14
exports.baseUrl = "https://scrt.link";
exports.baseUrl = 'https://scrt.link';
//# sourceMappingURL=constants.js.map

@@ -1,3 +0,3 @@

import { encryptMessage, decryptMessage, generateAlias, generateEncryptionKey } from "./utils";
import { CreateSecretOptions, SecretUrlFields } from "./types";
import { encryptMessage, decryptMessage, generateAlias, generateEncryptionKey } from './utils';
import { CreateSecretOptions, SecretUrlFields } from './types';
export declare type CreateSecret = (message: string, options?: CreateSecretOptions, baseUrl?: string) => Promise<{

@@ -4,0 +4,0 @@ alias: string;

@@ -13,3 +13,3 @@ "use strict";

const createSecret = (message, options = {}, baseUrl = constants_1.baseUrl) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const { alias = utils_1.generateAlias(), encryptionKey = utils_1.generateEncryptionKey(), password, secretType = "text", neogramDestructionMessage = "This message will self-destruct in…", neogramDestructionTimeout = 3, receiptApi, receiptEmail, receiptPhoneNumber, } = options;
const { alias = utils_1.generateAlias(), encryptionKey = utils_1.generateEncryptionKey(), password, secretType = 'text', neogramDestructionMessage = 'This message will self-destruct in…', neogramDestructionTimeout = 3, receiptApi, receiptEmail, receiptPhoneNumber, file, } = options;
if (password && ramda_1.is(String, password)) {

@@ -20,5 +20,5 @@ message = utils_1.encryptMessage(message, password);

message = utils_1.encryptMessage(message, encryptionKey);
const data = Object.assign(Object.assign({ alias,
const data = Object.assign(Object.assign(Object.assign({ alias,
message,
secretType, isEncryptedWithUserPassword: !!password }, (secretType === "neogram"
secretType, isEncryptedWithUserPassword: !!password }, (secretType === 'neogram'
? {

@@ -30,4 +30,8 @@ neogramDestructionMessage,

receiptEmail,
receiptPhoneNumber });
return utils_1.api(`${baseUrl}/api/secrets`, { method: "POST" }, ramda_1.reject(ramda_1.isNil, data)).then(() => ({
receiptPhoneNumber }), (secretType === 'file'
? {
file,
}
: {}));
return utils_1.api(`${baseUrl}/api/secrets`, { method: 'POST' }, ramda_1.reject(ramda_1.isNil, data)).then(() => ({
alias,

@@ -41,3 +45,3 @@ encryptionKey,

const secretRaw = yield utils_1.api(`${baseUrl}/api/secrets/${alias}`, {
method: "DELETE",
method: 'DELETE',
});

@@ -49,3 +53,3 @@ if (!secretRaw.message) {

if (!result) {
throw new Error("Decryption failed.");
throw new Error('Decryption failed.');
}

@@ -52,0 +56,0 @@ return Object.assign(Object.assign({}, secretRaw), { message: result });

@@ -1,2 +0,2 @@

export declare type SecretType = "text" | "url" | "neogram";
export declare type SecretType = 'text' | 'url' | 'neogram' | 'file';
export interface CreateSecretOptions {

@@ -12,6 +12,13 @@ alias?: string;

receiptApi?: Record<string, unknown>;
file?: {
bucket: string;
key: string;
type: string;
name: string;
size: number;
};
}
export declare type SecretUrlFields = Omit<CreateSecretOptions, "encryptionKey" | "password"> & {
export declare type SecretUrlFields = Omit<CreateSecretOptions, 'encryptionKey' | 'password'> & {
message: string;
isEncryptedWithUserPassword: boolean;
};

@@ -13,3 +13,3 @@ "use strict";

// Default options are marked with *
const response = yield cross_fetch_1.default(url, Object.assign(Object.assign({ method: "GET", headers: Object.assign({ "Content-Type": "application/json" }, options === null || options === void 0 ? void 0 : options.headers) }, options), (data ? { body: JSON.stringify(data) } : {})));
const response = yield cross_fetch_1.default(url, Object.assign(Object.assign({ method: 'GET', headers: Object.assign({ 'Content-Type': 'application/json' }, options === null || options === void 0 ? void 0 : options.headers) }, options), (data ? { body: JSON.stringify(data) } : {})));
if (!response.ok) {

@@ -16,0 +16,0 @@ const errorResponse = yield response.json();

module.exports = {
roots: ['<rootDir>/src'],
testMatch: [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
testMatch: ['**/__tests__/**/*.+(ts|tsx|js)', '**/?(*.)+(spec|test).+(ts|tsx|js)'],
transform: {
"^.+\\.(ts|tsx)$": "ts-jest"
'^.+\\.(ts|tsx)$': 'ts-jest',
},
}
{
"name": "scrt-link-core",
"version": "0.2.2",
"version": "0.2.3",
"description": "Core for scrt.link - a tool to securely share sensitive information online.",

@@ -42,5 +42,6 @@ "author": "Chris Chiller <kingchiller@protonmail.com>",

"@typescript-eslint/parser": "^4.19.0",
"esbuild": "^0.11.11",
"esbuild": "^0.13.15",
"eslint": "^7.22.0",
"jest": "^26.6.3",
"prettier": "^2.5.1",
"ts-jest": "^26.5.4",

@@ -47,0 +48,0 @@ "ts-node": "^9.1.1",

@@ -20,5 +20,5 @@ # scrt-link-core

```ts
import { createSecret } from "scrt-link-core";
import { createSecret } from 'scrt-link-core'
const { secretLink } = await createSecret("Some confidential information…");
const { secretLink } = await createSecret('Some confidential information…')
// https://scrt.link/l/CWmbcLtxzFRad8JJ#ReCMTkJkAtUqFF9ydBAWdYaz

@@ -68,6 +68,6 @@ ```

<script type="module">
import { createSecret } from "https://cdn.skypack.dev/scrt-link-core";
import { createSecret } from 'https://cdn.skypack.dev/scrt-link-core'
// Use as described above…
createSecret("Some confidential information…").then(({ secretLink }) => {});
createSecret('Some confidential information…').then(({ secretLink }) => {})
</script>

@@ -90,7 +90,5 @@ ```

// Functions are available on the window object
window
.createSecret("Some confidential information…")
.then(({ secretLink }) => {
console.log(`Success! Your secret link is: ${secretLink}`);
});
window.createSecret('Some confidential information…').then(({ secretLink }) => {
console.log(`Success! Your secret link is: ${secretLink}`)
})
</script>

@@ -97,0 +95,0 @@ </body>

@@ -5,21 +5,14 @@ /**

*/
import {
createSecret,
CreateSecret,
retrieveSecret,
RetrieveSecret,
} from "./main";
import { createSecret, CreateSecret, retrieveSecret, RetrieveSecret } from './main'
declare global {
interface Window {
createSecret: CreateSecret;
retrieveSecret: RetrieveSecret;
createSecret: CreateSecret
retrieveSecret: RetrieveSecret
}
}
window.createSecret = createSecret;
window.retrieveSecret = retrieveSecret;
window.createSecret = createSecret
window.retrieveSecret = retrieveSecret
console.log(
'Method "createSecret" and "retrieveSecret" were added to the window object."'
);
console.log('Method "createSecret" and "retrieveSecret" were added to the window object."')

@@ -1,3 +0,3 @@

export const urlAliasLength = 16; // 12
export const encryptionKeyLength = 24; // 14
export const baseUrl = "https://scrt.link";
export const urlAliasLength = 16 // 12
export const encryptionKeyLength = 24 // 14
export const baseUrl = 'https://scrt.link'

@@ -1,37 +0,32 @@

import {
createSecret,
retrieveSecret,
generateAlias,
generateEncryptionKey,
} from "./main";
import { urlAliasLength, encryptionKeyLength } from "./constants";
import { createSecret, retrieveSecret, generateAlias, generateEncryptionKey } from './main'
import { urlAliasLength, encryptionKeyLength } from './constants'
test("Generate alias", async () => {
expect(generateAlias()).toHaveLength(urlAliasLength);
});
test('Generate alias', async () => {
expect(generateAlias()).toHaveLength(urlAliasLength)
})
test("Generate encryption key", async () => {
expect(generateEncryptionKey()).toHaveLength(encryptionKeyLength);
});
test('Generate encryption key', async () => {
expect(generateEncryptionKey()).toHaveLength(encryptionKeyLength)
})
test("Create and retrieve secret", async () => {
const secretMessage = "I love you!";
const secret = await createSecret(secretMessage);
test('Create and retrieve secret', async () => {
const secretMessage = 'I love you!'
const secret = await createSecret(secretMessage)
expect(secret).toHaveProperty("secretLink");
expect(secret).toHaveProperty("alias");
expect(secret).toHaveProperty("encryptionKey");
expect(secret).toHaveProperty('secretLink')
expect(secret).toHaveProperty('alias')
expect(secret).toHaveProperty('encryptionKey')
const { alias, encryptionKey } = secret;
const { alias, encryptionKey } = secret
const { message } = await retrieveSecret(alias, encryptionKey);
const { message } = await retrieveSecret(alias, encryptionKey)
expect(message).toBe(secretMessage);
expect(message).toBe(secretMessage)
// Second attempt fails since secret is gone.
try {
await retrieveSecret(alias, encryptionKey);
await retrieveSecret(alias, encryptionKey)
} catch (error) {
expect(error.message).toContain("Secret not found");
expect(error.message).toContain('Secret not found')
}
});
})

@@ -1,11 +0,5 @@

import { reject, is, isNil } from "ramda";
import { baseUrl as defaultBaseUrl } from "./constants";
import {
encryptMessage,
decryptMessage,
generateAlias,
generateEncryptionKey,
api,
} from "./utils";
import { CreateSecretOptions, SecretUrlFields } from "./types";
import { reject, is, isNil } from 'ramda'
import { baseUrl as defaultBaseUrl } from './constants'
import { encryptMessage, decryptMessage, generateAlias, generateEncryptionKey, api } from './utils'
import { CreateSecretOptions, SecretUrlFields } from './types'

@@ -15,8 +9,8 @@ export type CreateSecret = (

options?: CreateSecretOptions,
baseUrl?: string
baseUrl?: string,
) => Promise<{
alias: string;
encryptionKey: string;
secretLink: string;
}>;
alias: string
encryptionKey: string
secretLink: string
}>

@@ -26,3 +20,3 @@ export const createSecret: CreateSecret = async (

options = {},
baseUrl = defaultBaseUrl
baseUrl = defaultBaseUrl,
) => {

@@ -33,4 +27,4 @@ const {

password,
secretType = "text",
neogramDestructionMessage = "This message will self-destruct in…",
secretType = 'text',
neogramDestructionMessage = 'This message will self-destruct in…',
neogramDestructionTimeout = 3,

@@ -40,10 +34,11 @@ receiptApi,

receiptPhoneNumber,
} = options;
file,
} = options
if (password && is(String, password)) {
message = encryptMessage(message, password);
message = encryptMessage(message, password)
}
// Default encryption
message = encryptMessage(message, encryptionKey);
message = encryptMessage(message, encryptionKey)

@@ -55,3 +50,3 @@ const data = {

isEncryptedWithUserPassword: !!password,
...(secretType === "neogram"
...(secretType === 'neogram'
? {

@@ -65,14 +60,15 @@ neogramDestructionMessage,

receiptPhoneNumber,
};
...(secretType === 'file'
? {
file,
}
: {}),
}
return api(
`${baseUrl}/api/secrets`,
{ method: "POST" },
reject(isNil, data)
).then(() => ({
return api(`${baseUrl}/api/secrets`, { method: 'POST' }, reject(isNil, data)).then(() => ({
alias,
encryptionKey,
secretLink: `${baseUrl}/l/${alias}#${encryptionKey}`,
}));
};
}))
}

@@ -82,4 +78,4 @@ export type RetrieveSecret = (

decryptionKey: string,
baseUrl?: string
) => Promise<Partial<SecretUrlFields>>;
baseUrl?: string,
) => Promise<Partial<SecretUrlFields>>

@@ -89,22 +85,19 @@ export const retrieveSecret: RetrieveSecret = async (

decryptionKey,
baseUrl = defaultBaseUrl
baseUrl = defaultBaseUrl,
) => {
const secretRaw = await api<Partial<SecretUrlFields>>(
`${baseUrl}/api/secrets/${alias}`,
{
method: "DELETE",
}
);
const secretRaw = await api<Partial<SecretUrlFields>>(`${baseUrl}/api/secrets/${alias}`, {
method: 'DELETE',
})
if (!secretRaw.message) {
throw new Error(`Couldn't retrieve secret message.`);
throw new Error(`Couldn't retrieve secret message.`)
}
const result = decryptMessage(secretRaw.message, decryptionKey);
const result = decryptMessage(secretRaw.message, decryptionKey)
if (!result) {
throw new Error("Decryption failed.");
throw new Error('Decryption failed.')
}
return { ...secretRaw, message: result };
};
return { ...secretRaw, message: result }
}

@@ -118,6 +111,6 @@ const ScrtLink = {

generateEncryptionKey,
};
}
export { encryptMessage, decryptMessage, generateAlias, generateEncryptionKey };
export { encryptMessage, decryptMessage, generateAlias, generateEncryptionKey }
export default ScrtLink;
export default ScrtLink

@@ -1,21 +0,25 @@

export type SecretType = "text" | "url" | "neogram";
export type SecretType = 'text' | 'url' | 'neogram' | 'file'
export interface CreateSecretOptions {
alias?: string;
secretType?: SecretType;
encryptionKey?: string;
neogramDestructionMessage?: string;
neogramDestructionTimeout?: number;
password?: string;
receiptEmail?: string;
receiptPhoneNumber?: string;
receiptApi?: Record<string, unknown>;
alias?: string
secretType?: SecretType
encryptionKey?: string
neogramDestructionMessage?: string
neogramDestructionTimeout?: number
password?: string
receiptEmail?: string
receiptPhoneNumber?: string
receiptApi?: Record<string, unknown>
file?: {
bucket: string
key: string
type: string
name: string
size: number
}
}
export type SecretUrlFields = Omit<
CreateSecretOptions,
"encryptionKey" | "password"
> & {
message: string;
isEncryptedWithUserPassword: boolean;
};
export type SecretUrlFields = Omit<CreateSecretOptions, 'encryptionKey' | 'password'> & {
message: string
isEncryptedWithUserPassword: boolean
}

@@ -1,7 +0,7 @@

import fetch from "cross-fetch";
import { AES, enc, SHA256 } from "crypto-js";
import { customAlphabet } from "nanoid";
import { nolookalikes } from "nanoid-dictionary";
import fetch from 'cross-fetch'
import { AES, enc, SHA256 } from 'crypto-js'
import { customAlphabet } from 'nanoid'
import { nolookalikes } from 'nanoid-dictionary'
import { urlAliasLength, encryptionKeyLength } from "./constants";
import { urlAliasLength, encryptionKeyLength } from './constants'

@@ -11,9 +11,9 @@ export async function api<T>(

options?: RequestInit,
data?: Record<string, unknown> | null
data?: Record<string, unknown> | null,
): Promise<T> {
// Default options are marked with *
const response = await fetch(url, {
method: "GET", // *GET, POST, PUT, DELETE, etc.
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
...options?.headers,

@@ -23,33 +23,32 @@ },

...(data ? { body: JSON.stringify(data) } : {}), // body data type must match "Content-Type" header
});
})
if (!response.ok) {
const errorResponse = await response.json();
throw errorResponse;
const errorResponse = await response.json()
throw errorResponse
}
return response.json() as Promise<T>;
return response.json() as Promise<T>
}
const createHash = (key: string): string => enc.Base64.stringify(SHA256(key));
const createHash = (key: string): string => enc.Base64.stringify(SHA256(key))
type EncryptMessage = (message: string, encryptionKey: string) => string;
type EncryptMessage = (message: string, encryptionKey: string) => string
export const encryptMessage: EncryptMessage = (message, encryptionKey) => {
const hash = createHash(encryptionKey);
return AES.encrypt(message, hash).toString();
};
const hash = createHash(encryptionKey)
return AES.encrypt(message, hash).toString()
}
type DecryptMessage = (message: string, decryptionKey: string) => string;
type DecryptMessage = (message: string, decryptionKey: string) => string
export const decryptMessage: DecryptMessage = (message, decryptionKey) => {
const hash = createHash(decryptionKey);
const bytes = AES.decrypt(message, hash);
return bytes.toString(enc.Utf8);
};
const hash = createHash(decryptionKey)
const bytes = AES.decrypt(message, hash)
return bytes.toString(enc.Utf8)
}
const generateNanoId = (length: number): string => {
const nanoid = customAlphabet(nolookalikes, length);
return nanoid();
};
export const generateAlias = (): string => generateNanoId(urlAliasLength);
export const generateEncryptionKey = (): string =>
generateNanoId(encryptionKeyLength);
const nanoid = customAlphabet(nolookalikes, length)
return nanoid()
}
export const generateAlias = (): string => generateNanoId(urlAliasLength)
export const generateEncryptionKey = (): string => generateNanoId(encryptionKeyLength)

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc