fix plugin path matching, add coverage

This commit is contained in:
Caleb Roseland 2023-11-24 13:15:26 -06:00
parent 5d35b4a995
commit 89fc14bb43
4 changed files with 72 additions and 4 deletions

View file

@ -169,10 +169,16 @@ export function parseDeepLink(deepLinkUrl: string): DeepLinkWithData {
return {type: DeepLink.Permalink, url: deepLinkUrl, data: {serverUrl, teamName, postId}};
}
const pluginMatch = match<{serverUrl: string; id: string}>(`:serverUrl(.*)/plugins/:id(${PLUGIN_ID_PATH_PATTERN})`)(url);
const pluginMatch = match<{serverUrl: string; id: string; route?: string[]}>(`:serverUrl(.*)/plugins/:id(${PLUGIN_ID_PATH_PATTERN})/:route+`)(url);
if (pluginMatch) {
const {params: {serverUrl, id}} = pluginMatch;
return {type: DeepLink.Plugin, url: deepLinkUrl, data: {serverUrl, teamName: '', id}};
const {params: {serverUrl, id, route}} = pluginMatch;
const data: DeepLinkWithData['data'] = {serverUrl, teamName: '', id};
if (route) {
data.route = route.join('/');
}
return {type: DeepLink.Plugin, url: deepLinkUrl, data};
}
} catch (err) {
// do nothing just return invalid deeplink

View file

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
export const ID_PATH_PATTERN = '[a-z0-9]{26}';
export const PLUGIN_ID_PATH_PATTERN = '^[a-zA-Z0-9-_.]+$';
export const PLUGIN_ID_PATH_PATTERN = '[a-zA-Z0-9-_.]{3,190}';
// This should cover:
// - Team name (lowercase english characters, numbers or -)

View file

@ -403,6 +403,67 @@ describe('UrlUtils', () => {
},
expected: null,
},
{
name: 'should match plugin path on a Server hosted in a Subpath',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/com.acme.abc-test/api/testroute',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: {
data: {
id: 'com.acme.abc-test',
route: 'api/testroute',
serverUrl: URL_PATH_NO_PROTOCOL,
teamName: '',
},
type: DeepLinkType.Plugin,
},
},
{
name: 'should match plugin path with single-level route',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_ab/testroute',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: {
data: {
id: 'abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_ab',
route: 'testroute',
serverUrl: URL_PATH_NO_PROTOCOL,
teamName: '',
},
type: DeepLinkType.Plugin,
},
},
{
name: 'should not match plugin path with invalid plugin id len=2',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/ab/api/testroute',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: null,
},
{
name: 'should not match plugin path with invalid plugin id len=191',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc/api/testroute',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: null,
},
{
name: 'should not match plugin path without a route',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/abc',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: null,
},
];
for (const test of tests) {

View file

@ -26,6 +26,7 @@ export interface DeepLinkGM extends DeepLink {
export interface DeepLinkPlugin extends DeepLink {
id: string;
route?: string;
}
export type DeepLinkType = typeof DeepLink[keyof typeof DeepLink];