Skip to content

Commit

Permalink
feat: add js-obfuscator tool.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Oct 29, 2022
1 parent 7aaeb99 commit b56a126
Show file tree
Hide file tree
Showing 16 changed files with 252 additions and 5 deletions.
10 changes: 6 additions & 4 deletions packages/components/src/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Fragment, PropsWithChildren, useState } from 'react';
import styled, { css, createGlobalStyle } from 'styled-components';
import copyTextToClipboard from '@uiw/copy-to-clipboard';
import { useTranslation } from 'react-i18next';
import { CopyIcon } from './Icon';

const GlobalStyle = createGlobalStyle`
Expand Down Expand Up @@ -54,23 +55,24 @@ export interface ButtonProps
}

export const CopyButton: React.FC<PropsWithChildren<ButtonProps>> = ({ children, ...other }) => {
const { t } = useTranslation(['common']);
const [success, setSuccess] = useState(false);
const [child, setChild] = useState('Copy');
const [type, setType] = useState<'copy' | 'copied'>('copy');
function handleClick(evn: React.MouseEvent<HTMLButtonElement>) {
copyTextToClipboard(`${other.value}`, (isCopy) => {
setSuccess(true);
setChild('Copied!');
setType('copied');
const timer = setTimeout(() => {
setSuccess(false);
setChild('Copy');
setType('copy');
clearTimeout(timer);
}, 2000);
});
}
return (
<Button {...other} success={success} className={success ? 'active' : ''} onClick={handleClick}>
<CopyIcon style={{ marginRight: 2 }} />
<span>{child}</span>
<span>{type === 'copy' ? t<string>('Copy', { ns: 'common' }) : t<string>('Copied', { ns: 'common' })}</span>
</Button>
);
};
16 changes: 16 additions & 0 deletions packages/components/src/CheckboxOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import styled from 'styled-components';

const Label = styled.label`
input {
vertical-align: middle;
}
`;

interface CheckboxOptionProps
extends React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> {}
export const CheckboxOption: React.FC<React.PropsWithChildren<CheckboxOptionProps>> = ({ children, ...other }) => (
<Label>
<input type="checkbox" {...other} />
{children}
</Label>
);
1 change: 1 addition & 0 deletions packages/components/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './Document';
export * from './Result';
export * from './Button';
export * from './CodeLineCopy';
export * from './CheckboxOption';
export * from './Spacing';
export * from './Input';
export * from './StyledLayout';
Expand Down
2 changes: 1 addition & 1 deletion packages/js-beautifier/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const Checkbox: React.FC<React.PropsWithChildren<CheckboxProps>> = ({ children,
);
};

export default function JSONFormat() {
export default function JSBeautifier() {
const { t } = useTranslation(['js-beautifier', 'common']);
const editor = useRef<ReactCodeMirrorRef>(null);
const [type, setType] = useState<Type>('minify');
Expand Down
27 changes: 27 additions & 0 deletions packages/js-obfuscator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@wcj/tools-react-js-obfuscator",
"version": "1.9.4",
"main": "./cjs/index.js",
"module": "./esm/index.js",
"scripts": {
"build": "tsbb build",
"watch": "tsbb watch"
},
"keywords": [],
"files": [
"cjs",
"esm",
"src"
],
"author": "Kenny Wong <wowohoo@qq.com>",
"license": "MIT",
"dependencies": {
"@codemirror/lang-javascript": "^6.0.0",
"@wcj/tools-react-components": "1.9.4",
"javascript-obfuscator": "~4.0.0"
},
"peerDependencies": {
"react": ">=16.14.0",
"react-dom": ">=16.14.0"
}
}
154 changes: 154 additions & 0 deletions packages/js-obfuscator/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { Fragment, useRef, useState } from 'react';
import {
StyledLayout,
CopyButton,
ResultCode,
Spacing,
CodeEditor,
Button,
Wrapper,
CheckboxOption,
ErrorLayout,
} from '@wcj/tools-react-components';
import { javascript } from '@codemirror/lang-javascript';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
import { obfuscate, ObfuscatorOptions } from 'javascript-obfuscator';
import * as sample from './sample';

const Info = styled.span`
color: var(--color-fg-subtle);
`;

const defaultOptions: ObfuscatorOptions = {
compact: true,
// compact: boolean;
// controlFlowFlattening: boolean;
// controlFlowFlatteningThreshold: number;
// deadCodeInjection: boolean;
// deadCodeInjectionThreshold: number;
// debugProtection: boolean;
// debugProtectionInterval: number;
// disableConsoleOutput: boolean;
// domainLock: string[];
// domainLockRedirectUrl: string;
// forceTransformStrings: string[];
// identifierNamesCache: TIdentifierNamesCache;
// identifierNamesGenerator: TTypeFromEnum<typeof IdentifierNamesGenerator>;
// identifiersDictionary: string[];
// identifiersPrefix: string;
// ignoreImports: boolean;
// inputFileName: string;
// log: boolean;
// numbersToExpressions: boolean;
// optionsPreset: TOptionsPreset;
// renameGlobals: boolean;
// renameProperties: boolean;
// renamePropertiesMode: TRenamePropertiesMode;
// reservedNames: string[];
// reservedStrings: string[];
// seed: string | number;
// selfDefending: boolean;
// simplify: boolean;
// sourceMap: boolean;
// sourceMapBaseUrl: string;
// sourceMapFileName: string;
// sourceMapMode: TTypeFromEnum<typeof SourceMapMode>;
// sourceMapSourcesMode: TTypeFromEnum<typeof SourceMapSourcesMode>;
// splitStrings: boolean;
// splitStringsChunkLength: number;
// stringArray: boolean;
// stringArrayCallsTransform: boolean;
// stringArrayCallsTransformThreshold: number;
// stringArrayEncoding: TStringArrayEncoding[];
// stringArrayIndexesType: TStringArrayIndexesType[];
// stringArrayIndexShift: boolean;
// stringArrayRotate: boolean;
// stringArrayShuffle: boolean;
// stringArrayWrappersChainedCalls: boolean;
// stringArrayWrappersCount: number;
// stringArrayWrappersParametersMaxCount: number;
// stringArrayWrappersType: TStringArrayWrappersType;
// stringArrayThreshold: number;
// target: TTypeFromEnum<typeof ObfuscationTarget>;
// transformObjectKeys: boolean;
// unicodeEscapeSequence: boolean;
};

export default function JSObfuscator() {
const [options, setOptions] = useState<any>(defaultOptions);
const { t } = useTranslation(['js-obfuscator', 'common']);
const editor = useRef<ReactCodeMirrorRef>(null);
const [type, setType] = useState<'raw' | 'obfuscator'>('raw');
const [value, setValue] = useState(sample.val || '');
const [valueObfuscate, setValueObfuscate] = useState('');
const [error, setError] = useState('');
function handleObfuscate() {
if (type === 'raw') {
const val = obfuscate(value, options);
setValueObfuscate(val.getObfuscatedCode());
} else {
}
setType(type === 'raw' ? 'obfuscator' : 'raw');
}
const codeSource = type === 'raw' ? value : valueObfuscate;
return (
<Wrapper>
<StyledLayout
title="JavaScript Obfuscator"
extra={
<Fragment>
<Button onClick={() => handleObfuscate()}>
{type === 'raw' ? t<string>('Obfuscator') : t<string>('Raw Code')}
</Button>
{codeSource && <CopyButton value={codeSource} />}
<Button
onClick={() => {
editor.current?.view?.focus();
setValue(sample.val);
setType('raw');
}}
>
{t<string>('Sample', { ns: 'common' })}
</Button>
</Fragment>
}
>
<CodeEditor
value={codeSource}
ref={editor}
height="calc(100vh - 87px)"
extensions={[javascript()]}
onChange={(value) => {
type === 'raw' ? setValue(value) : setValueObfuscate(value);
}}
/>
</StyledLayout>
<StyledLayout
title={t<string>('Options', { ns: 'common' })}
style={{ maxWidth: 420 }}
extra={
<Fragment>
<Button onClick={() => setOptions(defaultOptions)}>Reset</Button>
<Button onClick={() => setOptions({})}>None</Button>
</Fragment>
}
>
<ResultCode codeProps={{ style: { height: 'calc(100vh - 87px)', overflow: 'auto', margin: 0 } }}>
<Spacing>
<CheckboxOption
checked={!!options.compact}
onChange={({ target }) => {
setOptions({ ...options, ...{ compact: target.checked } });
}}
>
{t<string>('compact')} <Info>{t<string>('Compact code output on one line.')}</Info>
</CheckboxOption>
</Spacing>
</ResultCode>
</StyledLayout>
{error && <ErrorLayout>{error}</ErrorLayout>}
</Wrapper>
);
}
7 changes: 7 additions & 0 deletions packages/js-obfuscator/src/sample.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const js = `function hello(who = "world") { console.log(\`Hello, \${who}!\`) }`;
export const val = `function hello(who = "world") {
console.log(\`Hello, \${who}!\`)
return \`Hello, \${who}!\`
}
hello();
`;
9 changes: 9 additions & 0 deletions packages/js-obfuscator/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig",
"include": ["src"],
"compilerOptions": {
"baseUrl": ".",
"outDir": "cjs",
"noEmit": false
}
}
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@wcj/tools-react-html-to-markdown": "1.9.4",
"@wcj/tools-react-image-to-base64": "1.9.4",
"@wcj/tools-react-js-beautifier": "1.9.4",
"@wcj/tools-react-js-obfuscator": "1.9.4",
"@wcj/tools-react-json-format": "1.9.4",
"@wcj/tools-react-json-ini": "1.9.4",
"@wcj/tools-react-json-xml": "1.9.4",
Expand Down
2 changes: 2 additions & 0 deletions website/public/locales/cn/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
"Formatter": "格式化",
"Minify": "压缩",
"Options": "选项",
"Copy": "复制",
"Copied": "已复制",
"Sample": "示例"
}
5 changes: 5 additions & 0 deletions website/public/locales/cn/js-obfuscator.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Obfuscator": "混淆",
"Raw Code": "原始代码",
"Compact code output on one line.": "在一行上压缩代码输出"
}
3 changes: 3 additions & 0 deletions website/public/locales/cn/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"/js-beautifier": {
"label": "JS 美化/压缩"
},
"/js-obfuscator": {
"label": "JS 混淆器"
},
"/css-formatter": {
"label": "CSS 格式化/压缩"
},
Expand Down
3 changes: 3 additions & 0 deletions website/public/locales/en/js-obfuscator.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Obfuscator": "Obfuscator"
}
3 changes: 3 additions & 0 deletions website/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"/js-beautifier": {
"label": "JS Beautifier/Uglify"
},
"/js-obfuscator": {
"label": "JS Obfuscator"
},
"/css-formatter": {
"label": "CSS Formatter/Minify"
},
Expand Down
9 changes: 9 additions & 0 deletions website/src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const SVGOptimizer = Loadable(lazy(() => import('@wcj/tools-react-svg-optimizer'
const AmountInRMB = Loadable(lazy(() => import('@wcj/tools-react-amount-in-rmb')));
const SimplifiedTraditionalChinese = Loadable(lazy(() => import('@wcj/tools-react-simplified-traditional-chinese')));
const StandardChineseCharactersRMB = Loadable(lazy(() => import('@wcj/tools-react-standard-chinese-characters')));
const JSObfuscator = Loadable(lazy(() => import('@wcj/tools-react-js-obfuscator')));

export let routes: RouteObject[] = [
{
Expand All @@ -72,6 +73,10 @@ export let routes: RouteObject[] = [
index: true,
element: <HomePage title="Home - Web Tools" />,
},
{
path: 'home',
element: <HomePage title="Home - Web Tools" />,
},
{
path: 'url-encode',
element: <UrlEncode title="URL Encoder/Decoder - Web Tools" />,
Expand All @@ -84,6 +89,10 @@ export let routes: RouteObject[] = [
path: 'js-beautifier',
element: <JSBeautifier title="JS Beautifier/Uglify - Web Tools" />,
},
{
path: 'js-obfuscator',
element: <JSObfuscator title="JS Obfuscator - Web Tools" />,
},
{
path: 'text-case',
element: <TextCase title="Text Case - Web Tools" />,
Expand Down
5 changes: 5 additions & 0 deletions website/src/menus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export function useMenus() {
logo: 'js',
label: t('menu./js-beautifier.label'),
},
{
href: '/js-obfuscator',
logo: 'js',
label: t('menu./js-obfuscator.label'),
},
{
href: '/text-case',
logo: 'text',
Expand Down

0 comments on commit b56a126

Please sign in to comment.