diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5c67208..4dd9ffb7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - run: corepack enable - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: 'pnpm' - name: Install dependencies diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index b5b04096..13b787ef 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: 'pnpm' - name: Get Playwright version diff --git a/locales/en.yml b/locales/en.yml index 50d48af9..d09d435a 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -7,7 +7,7 @@ home: toggleMenu: 'Toggle menu' home: Home uiLib: 'UI Lib' - support: 'Support IT Tools development' + support: 'Support IT-Tools development' buyMeACoffee: 'Buy me a coffee' follow: title: 'You like it-tools?' @@ -15,7 +15,7 @@ home: githubRepository: 'IT-Tools GitHub repository' p2: 'or follow us on' twitterAccount: 'IT-Tools Twitter account' - thankYou: 'Thank you !' + thankYou: 'Thank you!' nav: github: 'GitHub repository' githubRepository: 'IT-Tools GitHub repository' @@ -72,7 +72,7 @@ tools: password-strength-analyser: title: Password strength analyser - description: Discover the strength of your password with this client side only password strength analyser and crack time estimation tool. + description: Discover the strength of your password with this client-side-only password strength analyser and crack time estimation tool. chronometer: title: Chronometer @@ -98,7 +98,7 @@ tools: svg-placeholder-generator: title: SVG placeholder generator - description: Generate svg images to use as placeholder in your applications. + description: Generate svg images to use as a placeholder in your applications. json-to-csv: title: JSON to CSV @@ -126,11 +126,11 @@ tools: crontab-generator: title: Crontab generator - description: Validate and generate crontab and get the human readable description of the cron schedule. + description: Validate and generate crontab and get the human-readable description of the cron schedule. http-status-codes: title: HTTP status codes - description: The list of all HTTP status codes their name and their meaning. + description: The list of all HTTP status codes, their name, and their meaning. sql-prettify: title: SQL prettify and format @@ -142,7 +142,7 @@ tools: git-memo: title: Git cheatsheet - description: Git is a decentralized version management software. With this cheatsheet you will have a quick access to the most common git commands. + description: Git is a decentralized version management software. With this cheatsheet, you will have quick access to the most common git commands. slugify-string: title: Slugify string @@ -150,7 +150,7 @@ tools: encryption: title: Encrypt / decrypt text - description: Encrypt and decrypt text clear text using crypto algorithm like AES, TripleDES, Rabbit or RC4. + description: Encrypt clear text and decrypt ciphertext using crypto algorithms like AES, TripleDES, Rabbit or RC4. random-port-generator: title: Random port generator @@ -158,11 +158,11 @@ tools: yaml-prettify: title: YAML prettify and format - description: Prettify your YAML string to a human friendly readable format. + description: Prettify your YAML string into a friendly, human-readable format. eta-calculator: title: ETA calculator - description: An ETA (Estimated Time of Arrival) calculator to know the approximate end time of a task, for example the moment of ending of a download. + description: An ETA (Estimated Time of Arrival) calculator to determine the approximate end time of a task, for example, the end time and duration of a file download. roman-numeral-converter: title: Roman numeral converter @@ -174,11 +174,11 @@ tools: bip39-generator: title: BIP39 passphrase generator - description: Generate BIP39 passphrase from existing or random mnemonic, or get the mnemonic from the passphrase. + description: Generate a BIP39 passphrase from an existing or random mnemonic, or get the mnemonic from the passphrase. base64-file-converter: title: Base64 file converter - description: Convert string, files or images into a it\'s base64 representation. + description: Convert a string, file, or image into its base64 representation. list-converter: title: List converter @@ -186,7 +186,7 @@ tools: base64-string-converter: title: Base64 string encoder/decoder - description: Simply encode and decode string into a their base64 representation. + description: Simply encode and decode strings into their base64 representation. toml-to-yaml: title: TOML to YAML @@ -198,15 +198,15 @@ tools: json-to-yaml-converter: title: JSON to YAML converter - description: Simply convert JSON to YAML with this live online converter. + description: Simply convert JSON to YAML with this online live converter. url-parser: - title: Url parser - description: Parse an url string to get all the different parts (protocol, origin, params, port, username-password, ...) + title: URL parser + description: Parse a URL into its separate constituent parts (protocol, origin, params, port, username-password, ...) iban-validator-and-parser: title: IBAN validator and parser - description: Validate and parse IBAN numbers. Check if IBAN is valid and get the country, BBAN, if it is a QR-IBAN and the IBAN friendly format. + description: Validate and parse IBAN numbers. Check if an IBAN is valid and get the country, BBAN, if it is a QR-IBAN and the IBAN friendly format. user-agent-parser: title: User-agent parser @@ -218,27 +218,27 @@ tools: case-converter: title: Case converter - description: Change the case of a string and chose between different formats + description: Transform the case of a string and choose between different formats html-entities: - title: Escape html entities - description: Escape or unescape html entities (replace <,>, &, " and \' to their html version) + title: Escape HTML entities + description: Escape or unescape HTML entities (replace characters like <,>, &, " and \' with their HTML version) json-prettify: title: JSON prettify and format - description: Prettify your JSON string to a human friendly readable format. + description: Prettify your JSON string into a friendly, human-readable format. docker-run-to-docker-compose-converter: title: Docker run to Docker compose converter - description: Turns docker run commands into docker-compose files! + description: Transforms "docker run" commands into docker-compose files! mac-address-lookup: title: MAC address lookup description: Find the vendor and manufacturer of a device by its MAC address. mime-types: - title: Mime types - description: Convert mime types to extensions and vice-versa. + title: MIME types + description: Convert MIME types to file extensions and vice-versa. toml-to-json: title: TOML to JSON @@ -250,19 +250,19 @@ tools: qrcode-generator: title: QR Code generator - description: Generate and download QR-code for an url or just a text and customize the background and foreground colors. + description: Generate and download a QR code for a URL (or just plain text), and customize the background and foreground colors. wifi-qrcode-generator: title: WiFi QR Code generator - description: Generate and download QR-codes for quick connections to WiFi networks. + description: Generate and download QR codes for quick connections to WiFi networks. xml-formatter: title: XML formatter - description: Prettify your XML string to a human friendly readable format. + description: Prettify your XML string into a friendly, human-readable format. temperature-converter: title: Temperature converter - description: Temperature degrees conversions for Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur and Rømer. + description: Degrees temperature conversions for Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur, and Rømer. chmod-calculator: title: Chmod calculator @@ -270,11 +270,11 @@ tools: rsa-key-pair-generator: title: RSA key pair generator - description: Generate new random RSA private and public key pem certificates. + description: Generate a new random RSA private and public pem certificate key pair. html-wysiwyg-editor: title: HTML WYSIWYG editor - description: Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately. + description: Online, feature-rich WYSIWYG HTML editor which generates the source code of the content immediately. yaml-to-toml: title: YAML to TOML @@ -302,15 +302,15 @@ tools: ipv4-subnet-calculator: title: IPv4 subnet calculator - description: Parse your IPv4 CIDR blocks and get all the info you need about your sub network. + description: Parse your IPv4 CIDR blocks and get all the info you need about your subnet. og-meta-generator: title: Open graph meta generator - description: Generate open-graph and socials html meta tags for your website. + description: Generate open-graph and socials HTML meta tags for your website. ipv6-ula-generator: title: IPv6 ULA generator - description: Generate your own local, non-routable IP addresses on your network according to RFC4193. + description: Generate your own local, non-routable IP addresses for your network according to RFC4193. hash-text: title: Hash text @@ -330,7 +330,7 @@ tools: json-minify: title: JSON minify - description: Minify and compress your JSON by removing unnecessary white spaces. + description: Minify and compress your JSON by removing unnecessary whitespace. ulid-generator: title: ULID generator @@ -342,31 +342,31 @@ tools: base-converter: title: Integer base converter - description: Convert number between different bases (decimal, hexadecimal, binary, octal, base64, ...) + description: Convert a number between different bases (decimal, hexadecimal, binary, octal, base64, ...) yaml-to-json-converter: title: YAML to JSON converter - description: Simply convert YAML to JSON with this live online converter. + description: Simply convert YAML to JSON with this online live converter. uuid-generator: title: UUIDs generator description: A Universally Unique Identifier (UUID) is a 128-bit number used to identify information in computer systems. The number of possible UUIDs is 16^32, which is 2^128 or about 3.4x10^38 (which is a lot!). ipv4-address-converter: - title: Ipv4 address converter - description: Convert an ip address into decimal, binary, hexadecimal or event in ipv6 + title: IPv4 address converter + description: Convert an IP address into decimal, binary, hexadecimal, or even an IPv6 representation of it. text-statistics: title: Text statistics - description: Get information about a text, the amount of characters, the amount of words, it\'s size, ... + description: Get information about a text, the number of characters, the number of words, its size in bytes, ... text-to-nato-alphabet: title: Text to NATO alphabet - description: Transform text into NATO phonetic alphabet for oral transmission. + description: Transform text into the NATO phonetic alphabet for oral transmission. basic-auth-generator: title: Basic auth generator - description: Generate a base64 basic auth header from an username and a password. + description: Generate a base64 basic auth header from a username and password. text-to-unicode: title: Text to Unicode @@ -374,7 +374,7 @@ tools: ipv4-range-expander: title: IPv4 range expander - description: Given a start and an end IPv4 address this tool calculates a valid IPv4 network with its CIDR notation. + description: Given a start and an end IPv4 address, this tool calculates a valid IPv4 subnet along with its CIDR notation. text-diff: title: Text diff @@ -385,9 +385,9 @@ tools: description: Generate and validate time-based OTP (one time password) for multi-factor authentication. url-encoder: - title: Encode/decode url formatted strings - description: Encode to url-encoded format (also known as "percent-encoded") or decode from it. + title: Encode/decode URL-formatted strings + description: Encode text to URL-encoded format (also known as "percent-encoded"), or decode from it. text-to-binary: title: Text to ASCII binary - description: Convert text to its ASCII binary representation and vice versa. + description: Convert text to its ASCII binary representation and vice-versa. diff --git a/playwright.config.ts b/playwright.config.ts index 3caa0612..5257c526 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -9,7 +9,7 @@ const useWebServer = process.env.NO_WEB_SERVER !== 'true'; */ export default defineConfig({ testDir: './src', - testMatch: /.*\.e2e\.(spec\.)?ts/, + testMatch: /\.e2e\.(spec\.)?ts$/, /* Run tests in files in parallel */ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ @@ -57,7 +57,7 @@ export default defineConfig({ && { webServer: { command: 'npm run preview', - url: 'http://127.0.0.1:5050', + url: 'http://localhost:5050', reuseExistingServer: !isCI, }, } diff --git a/src/tools/bcrypt/bcrypt.vue b/src/tools/bcrypt/bcrypt.vue index c28c20bf..d4881299 100644 --- a/src/tools/bcrypt/bcrypt.vue +++ b/src/tools/bcrypt/bcrypt.vue @@ -28,7 +28,7 @@ const compareMatch = computed(() => compareSync(compareString.value, compareHash mb-2 /> - + diff --git a/src/tools/index.ts b/src/tools/index.ts index 6e3d4900..c96422ec 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -6,6 +6,7 @@ import { tool as asciiTextDrawer } from './ascii-text-drawer'; import { tool as textToUnicode } from './text-to-unicode'; import { tool as certificateKeyParser } from './certificate-key-parser'; +import { tool as safelinkDecoder } from './safelink-decoder'; import { tool as pdfSignatureChecker } from './pdf-signature-checker'; import { tool as numeronymGenerator } from './numeronym-generator'; import { tool as macAddressGenerator } from './mac-address-generator'; @@ -140,6 +141,7 @@ export const toolsByCategory: ToolCategory[] = [ userAgentParser, httpStatusCodes, jsonDiff, + safelinkDecoder, ], }, { diff --git a/src/tools/integer-base-converter/integer-base-converter.model.test.ts b/src/tools/integer-base-converter/integer-base-converter.model.test.ts index d0387b64..c7d7db79 100644 --- a/src/tools/integer-base-converter/integer-base-converter.model.test.ts +++ b/src/tools/integer-base-converter/integer-base-converter.model.test.ts @@ -11,6 +11,9 @@ describe('integer-base-converter', () => { expect(convertBase({ value: '10100101', fromBase: 2, toBase: 16 })).toEqual('a5'); expect(convertBase({ value: '192654', fromBase: 10, toBase: 8 })).toEqual('570216'); expect(convertBase({ value: 'zz', fromBase: 64, toBase: 10 })).toEqual('2275'); + expect(convertBase({ value: '42540766411283223938465490632011909384', fromBase: 10, toBase: 10 })).toEqual('42540766411283223938465490632011909384'); + expect(convertBase({ value: '42540766411283223938465490632011909384', fromBase: 10, toBase: 16 })).toEqual('20010db8000085a300000000ac1f8908'); + expect(convertBase({ value: '20010db8000085a300000000ac1f8908', fromBase: 16, toBase: 10 })).toEqual('42540766411283223938465490632011909384'); }); }); }); diff --git a/src/tools/integer-base-converter/integer-base-converter.model.ts b/src/tools/integer-base-converter/integer-base-converter.model.ts index b4470e57..da0fe77f 100644 --- a/src/tools/integer-base-converter/integer-base-converter.model.ts +++ b/src/tools/integer-base-converter/integer-base-converter.model.ts @@ -5,16 +5,16 @@ export function convertBase({ value, fromBase, toBase }: { value: string; fromBa let decValue = value .split('') .reverse() - .reduce((carry: number, digit: string, index: number) => { + .reduce((carry: bigint, digit: string, index: number) => { if (!fromRange.includes(digit)) { throw new Error(`Invalid digit "${digit}" for base ${fromBase}.`); } - return (carry += fromRange.indexOf(digit) * fromBase ** index); - }, 0); + return (carry += BigInt(fromRange.indexOf(digit)) * BigInt(fromBase) ** BigInt(index)); + }, 0n); let newValue = ''; while (decValue > 0) { - newValue = toRange[decValue % toBase] + newValue; - decValue = (decValue - (decValue % toBase)) / toBase; + newValue = toRange[Number(decValue % BigInt(toBase))] + newValue; + decValue = (decValue - (decValue % BigInt(toBase))) / BigInt(toBase); } return newValue || '0'; } diff --git a/src/tools/safelink-decoder/index.ts b/src/tools/safelink-decoder/index.ts new file mode 100644 index 00000000..ef865108 --- /dev/null +++ b/src/tools/safelink-decoder/index.ts @@ -0,0 +1,12 @@ +import { Mailbox } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Outlook Safelink decoder', + path: '/safelink-decoder', + description: 'Decode Outlook SafeLink links', + keywords: ['outlook', 'safelink', 'decoder'], + component: () => import('./safelink-decoder.vue'), + icon: Mailbox, + createdAt: new Date('2024-03-11'), +}); diff --git a/src/tools/safelink-decoder/safelink-decoder.service.test.ts b/src/tools/safelink-decoder/safelink-decoder.service.test.ts new file mode 100644 index 00000000..b601f01e --- /dev/null +++ b/src/tools/safelink-decoder/safelink-decoder.service.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from 'vitest'; +import { decodeSafeLinksURL } from './safelink-decoder.service'; + +describe('safelink-decoder', () => { + describe('decodeSafeLinksURL', () => { + describe('decode outlook safelink urls', () => { + it('should decode basic safelink urls', () => { + expect(decodeSafeLinksURL('https://aus01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3Dsafelink%26rlz%3D1&data=05%7C02%7C%7C1ed07253975b46da1d1508dc3443752a%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638442711583216725%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=%2BQY0HBnnxfI7pzZoxzlhZdDvYu80LwQB0zUUjrffVnk%3D&reserved=0')) + .toBe('https://www.google.com/search?q=safelink&rlz=1'); + }); + it('should decode encoded safelink urls', () => { + expect(decodeSafeLinksURL('https://aus01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3Dsafelink%26rlz%3D1&data=05%7C02%7C%7C1ed07253975b46da1d1508dc3443752a%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638442711583216725%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=%2BQY0HBnnxfI7pzZoxzlhZdDvYu80LwQB0zUUjrffVnk%3D&reserved=0')) + .toBe('https://www.google.com/search?q=safelink&rlz=1'); + }); + it('throw on not outlook safelink urls', () => { + expect(() => decodeSafeLinksURL('https://google.com')) + .toThrow('Invalid SafeLinks URL provided'); + }); + }); + }); +}); diff --git a/src/tools/safelink-decoder/safelink-decoder.service.ts b/src/tools/safelink-decoder/safelink-decoder.service.ts new file mode 100644 index 00000000..96be00ab --- /dev/null +++ b/src/tools/safelink-decoder/safelink-decoder.service.ts @@ -0,0 +1,7 @@ +export function decodeSafeLinksURL(safeLinksUrl: string) { + if (!safeLinksUrl.match(/\.safelinks\.protection\.outlook\.com/)) { + throw new Error('Invalid SafeLinks URL provided'); + } + + return new URL(safeLinksUrl).searchParams.get('url'); +} diff --git a/src/tools/safelink-decoder/safelink-decoder.vue b/src/tools/safelink-decoder/safelink-decoder.vue new file mode 100644 index 00000000..01337eb2 --- /dev/null +++ b/src/tools/safelink-decoder/safelink-decoder.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/tools/url-encoder/url-encoder.vue b/src/tools/url-encoder/url-encoder.vue index c43f8193..19025190 100644 --- a/src/tools/url-encoder/url-encoder.vue +++ b/src/tools/url-encoder/url-encoder.vue @@ -23,7 +23,7 @@ const decodeInput = ref('Hello%20world%20%3A)'); const decodeOutput = computed(() => withDefaultOnError(() => decodeURIComponent(decodeInput.value), '')); const decodeValidation = useValidation({ - source: encodeInput, + source: decodeInput, rules: [ { validator: value => isNotThrowing(() => decodeURIComponent(value)),