Skip to content

Commit

Permalink
feat(new tool): Outlook Safelink Decoder (#911)
Browse files Browse the repository at this point in the history
* feat(new tool): Outlook Safelink Decoder

Fix #897

* Use native URL parsing

Co-authored-by: Corentin THOMASSET <[email protected]>

* Update src/tools/safelink-decoder/index.ts

---------

Co-authored-by: Corentin THOMASSET <[email protected]>
  • Loading branch information
sharevb and CorentinTh authored Mar 11, 2024
1 parent fe349ad commit d3b32cc
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { tool as basicAuthGenerator } from './basic-auth-generator';
import { tool as asciiTextDrawer } from './ascii-text-drawer';

import { tool as textToUnicode } from './text-to-unicode';

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';
Expand Down Expand Up @@ -127,6 +127,7 @@ export const toolsByCategory: ToolCategory[] = [
userAgentParser,
httpStatusCodes,
jsonDiff,
safelinkDecoder,
],
},
{
Expand Down
12 changes: 12 additions & 0 deletions src/tools/safelink-decoder/index.ts
Original file line number Diff line number Diff line change
@@ -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'),
});
21 changes: 21 additions & 0 deletions src/tools/safelink-decoder/safelink-decoder.service.test.ts
Original file line number Diff line number Diff line change
@@ -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&amp;data=05%7C02%7C%7C1ed07253975b46da1d1508dc3443752a%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638442711583216725%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&amp;sdata=%2BQY0HBnnxfI7pzZoxzlhZdDvYu80LwQB0zUUjrffVnk%3D&amp;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');
});
});
});
});
7 changes: 7 additions & 0 deletions src/tools/safelink-decoder/safelink-decoder.service.ts
Original file line number Diff line number Diff line change
@@ -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');
}
32 changes: 32 additions & 0 deletions src/tools/safelink-decoder/safelink-decoder.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script setup lang="ts">
import { decodeSafeLinksURL } from './safelink-decoder.service';
import TextareaCopyable from '@/components/TextareaCopyable.vue';
const inputSafeLinkUrl = ref('');
const outputDecodedUrl = computed(() => {
try {
return decodeSafeLinksURL(inputSafeLinkUrl.value);
}
catch (e: any) {
return e.toString();
}
});
</script>

<template>
<div>
<c-input-text
v-model:value="inputSafeLinkUrl"
raw-text
placeholder="Your input Outlook SafeLink Url..."
autofocus
label="Your input Outlook SafeLink Url:"
/>

<n-divider />

<n-form-item label="Output decoded URL:">
<TextareaCopyable :value="outputDecodedUrl" :word-wrap="true" />
</n-form-item>
</div>
</template>

0 comments on commit d3b32cc

Please sign in to comment.