11744 emails broken image in emails (#12265)
- refactor file tokens - update file token management - generate one token per file per workspaceId - move token from query params to url path
This commit is contained in:
@ -16,6 +16,7 @@ export {
|
||||
} from './image/getLogoUrlFromDomainName';
|
||||
export { capitalize } from './strings/capitalize';
|
||||
export { absoluteUrlSchema } from './url/absoluteUrlSchema';
|
||||
export { buildSignedPath } from './url/buildSignedPath';
|
||||
export { getAbsoluteUrlOrThrow } from './url/getAbsoluteUrlOrThrow';
|
||||
export { getUrlHostnameOrThrow } from './url/getUrlHostnameOrThrow';
|
||||
export { isValidHostname } from './url/isValidHostname';
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
import { buildSignedPath } from '@/utils';
|
||||
|
||||
describe('buildSignedPath', () => {
|
||||
it('should build a signed path', () => {
|
||||
expect(
|
||||
buildSignedPath({ path: 'folder/test.txt', token: 'tokenValue' }),
|
||||
).toBe('folder/tokenValue/test.txt');
|
||||
});
|
||||
|
||||
it('should build a signed path with original subFolder', () => {
|
||||
expect(
|
||||
buildSignedPath({
|
||||
path: 'folder/original/test.txt',
|
||||
token: 'tokenValue',
|
||||
}),
|
||||
).toBe('folder/original/tokenValue/test.txt');
|
||||
});
|
||||
|
||||
it('should build a signed path with multiple dots filename', () => {
|
||||
expect(
|
||||
buildSignedPath({
|
||||
path: 'folder/test.data.12032026.txt',
|
||||
token: 'tokenValue',
|
||||
}),
|
||||
).toBe('folder/tokenValue/test.data.12032026.txt');
|
||||
});
|
||||
|
||||
it('should throw when building signed path with missing filename', () => {
|
||||
expect(() =>
|
||||
buildSignedPath({
|
||||
path: 'folder/',
|
||||
token: 'tokenValue',
|
||||
}),
|
||||
).toThrow(
|
||||
"Filename empty: cannot build signed path from folderPath 'folder/'",
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw when building signed path with empty path', () => {
|
||||
expect(() =>
|
||||
buildSignedPath({
|
||||
path: '',
|
||||
token: 'tokenValue',
|
||||
}),
|
||||
).toThrow("Filename empty: cannot build signed path from folderPath ''");
|
||||
});
|
||||
|
||||
it('should ignore absolute https urls', () => {
|
||||
expect(
|
||||
buildSignedPath({
|
||||
path: 'https://twentyhq.github.io/placeholder-images/workspaces/twenty-logo.png',
|
||||
token: 'tokenValue',
|
||||
}),
|
||||
).toBe(
|
||||
'https://twentyhq.github.io/placeholder-images/workspaces/twenty-logo.png',
|
||||
);
|
||||
});
|
||||
|
||||
it('should ignore absolute http urls', () => {
|
||||
expect(
|
||||
buildSignedPath({
|
||||
path: 'http://twentyhq.github.io/placeholder-images/workspaces/twenty-logo.png',
|
||||
token: 'tokenValue',
|
||||
}),
|
||||
).toBe(
|
||||
'http://twentyhq.github.io/placeholder-images/workspaces/twenty-logo.png',
|
||||
);
|
||||
});
|
||||
});
|
||||
25
packages/twenty-shared/src/utils/url/buildSignedPath.ts
Normal file
25
packages/twenty-shared/src/utils/url/buildSignedPath.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
|
||||
export const buildSignedPath = ({
|
||||
path,
|
||||
token,
|
||||
}: {
|
||||
path: string;
|
||||
token: string;
|
||||
}) => {
|
||||
if (path.startsWith('https:') || path.startsWith('http:')) {
|
||||
return path;
|
||||
}
|
||||
|
||||
const directories = path.split('/');
|
||||
|
||||
const filename = directories.pop();
|
||||
|
||||
if (!isNonEmptyString(filename)) {
|
||||
throw new Error(
|
||||
`Filename empty: cannot build signed path from folderPath '${path}'`,
|
||||
);
|
||||
}
|
||||
|
||||
return `${directories.join('/')}/${token}/${filename}`;
|
||||
};
|
||||
@ -3,3 +3,4 @@ export * from './getAbsoluteUrlOrThrow';
|
||||
export * from './getUrlHostnameOrThrow';
|
||||
export * from './isValidHostname';
|
||||
export * from './isValidUrl';
|
||||
export * from './buildSignedPath';
|
||||
|
||||
Reference in New Issue
Block a user