Skip to content

Commit 2f8199c

Browse files
committed
refactor(mdw): scope more precisely the URL try/catch to let malformed params throw an error
1 parent 59a14b1 commit 2f8199c

File tree

2 files changed

+89
-86
lines changed

2 files changed

+89
-86
lines changed

src/middlewares/format-firebase-dynamic-links.ts

Lines changed: 65 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -63,93 +63,93 @@ export function FormatFirebaseDynamicLinksMiddleware(
6363
options: FormatFirebaseDynamicLinksOptions
6464
): Middleware {
6565
return (properties, element, next) => {
66+
let url: URL;
6667
try {
67-
const url = new URL(properties.href);
68-
let androidStoreUrl: URL | undefined;
69-
let iosStoreUrl: URL | undefined;
68+
url = new URL(properties.href);
69+
} catch (err) {
70+
// In case it's not a valid format the middleware is skipped without affecting next ones
71+
return next();
72+
}
7073

71-
const dynamicLink = new URL(options.dynamicLinkBase);
72-
dynamicLink.searchParams.set('link', properties.href);
74+
let androidStoreUrl: URL | undefined;
75+
let iosStoreUrl: URL | undefined;
7376

74-
if (options.android) {
75-
dynamicLink.searchParams.set('apn', options.android.storeId);
77+
const dynamicLink = new URL(options.dynamicLinkBase);
78+
dynamicLink.searchParams.set('link', properties.href);
7679

77-
if (options.android.storeLink) {
78-
androidStoreUrl = new URL(options.android.storeLink);
79-
}
80+
if (options.android) {
81+
dynamicLink.searchParams.set('apn', options.android.storeId);
82+
83+
if (options.android.storeLink) {
84+
androidStoreUrl = new URL(options.android.storeLink);
8085
}
86+
}
8187

82-
if (options.ios) {
83-
dynamicLink.searchParams.set('isi', options.ios.storeId);
84-
dynamicLink.searchParams.set('ibi', options.ios.bundleId);
88+
if (options.ios) {
89+
dynamicLink.searchParams.set('isi', options.ios.storeId);
90+
dynamicLink.searchParams.set('ibi', options.ios.bundleId);
8591

86-
if (options.ios.storeLink) {
87-
iosStoreUrl = new URL(options.ios.storeLink);
88-
}
89-
90-
if (options.ios.nativeScheme) {
91-
dynamicLink.searchParams.set('ius', options.ios.nativeScheme);
92-
}
92+
if (options.ios.storeLink) {
93+
iosStoreUrl = new URL(options.ios.storeLink);
94+
}
9395

94-
dynamicLink.searchParams.set(
95-
'efr',
96-
options.ios.skipAppPreviewPage || '1'
97-
);
96+
if (options.ios.nativeScheme) {
97+
dynamicLink.searchParams.set('ius', options.ios.nativeScheme);
9898
}
9999

100-
if (
101-
options.injectUtmParamsInDynamicLink ||
102-
options.injectUtmParamsInFallback
103-
) {
104-
const urlParams = url.searchParams;
100+
dynamicLink.searchParams.set(
101+
'efr',
102+
options.ios.skipAppPreviewPage || '1'
103+
);
104+
}
105105

106-
// Get UTM parameters from the original link
107-
Object.values(FirebaseUtmParamEnum).forEach(utmKey => {
108-
const utmValue = urlParams.get(utmKey);
106+
if (
107+
options.injectUtmParamsInDynamicLink ||
108+
options.injectUtmParamsInFallback
109+
) {
110+
const urlParams = url.searchParams;
109111

110-
if (utmValue) {
111-
if (options.injectUtmParamsInDynamicLink) {
112-
dynamicLink.searchParams.set(utmKey, utmValue);
113-
}
112+
// Get UTM parameters from the original link
113+
Object.values(FirebaseUtmParamEnum).forEach(utmKey => {
114+
const utmValue = urlParams.get(utmKey);
114115

115-
if (options.injectUtmParamsInFallback) {
116-
if (androidStoreUrl) {
117-
androidStoreUrl.searchParams.set(utmKey, utmValue);
118-
}
116+
if (utmValue) {
117+
if (options.injectUtmParamsInDynamicLink) {
118+
dynamicLink.searchParams.set(utmKey, utmValue);
119+
}
119120

120-
if (iosStoreUrl) {
121-
iosStoreUrl.searchParams.set(utmKey, utmValue);
122-
}
121+
if (options.injectUtmParamsInFallback) {
122+
if (androidStoreUrl) {
123+
androidStoreUrl.searchParams.set(utmKey, utmValue);
123124
}
124-
}
125-
});
126-
}
127125

128-
// Fallback link (after UTM manipulations because they can be affected)
129-
if (options.usePlatformLinkAsFallback !== false) {
130-
if ((platform as any).os.family === 'iOS' && iosStoreUrl) {
131-
dynamicLink.searchParams.set('ofl', iosStoreUrl.toString());
132-
} else if (
133-
(platform as any).os.family === 'Android' &&
134-
androidStoreUrl
135-
) {
136-
dynamicLink.searchParams.set('ofl', androidStoreUrl.toString());
126+
if (iosStoreUrl) {
127+
iosStoreUrl.searchParams.set(utmKey, utmValue);
128+
}
129+
}
137130
}
138-
}
131+
});
132+
}
139133

140-
if (options.overrideParams) {
141-
for (const [paramKey, paramValue] of Object.entries(
142-
options.overrideParams
143-
)) {
144-
dynamicLink.searchParams.set(paramKey, paramValue);
145-
}
134+
// Fallback link (after UTM manipulations because they can be affected)
135+
if (options.usePlatformLinkAsFallback !== false) {
136+
if ((platform as any).os.family === 'iOS' && iosStoreUrl) {
137+
dynamicLink.searchParams.set('ofl', iosStoreUrl.toString());
138+
} else if ((platform as any).os.family === 'Android' && androidStoreUrl) {
139+
dynamicLink.searchParams.set('ofl', androidStoreUrl.toString());
146140
}
141+
}
147142

148-
properties.href = dynamicLink.toString();
149-
} catch (err) {
150-
// In case it's not a valid format the middleware is skipped without affecting next ones
143+
if (options.overrideParams) {
144+
for (const [paramKey, paramValue] of Object.entries(
145+
options.overrideParams
146+
)) {
147+
dynamicLink.searchParams.set(paramKey, paramValue);
148+
}
151149
}
152150

151+
properties.href = dynamicLink.toString();
152+
153153
next();
154154
};
155155
}

src/middlewares/set-utm-parameters.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,35 +39,38 @@ export function SetUtmParametersMiddleware(
3939
options: SetUtmParametersOptions
4040
): Middleware {
4141
return (properties, element, next) => {
42+
let url: URL;
4243
try {
43-
const url = new URL(properties.href);
44-
const urlParams = url.searchParams;
45-
let existingUtmParams: boolean = false;
44+
url = new URL(properties.href);
45+
} catch (err) {
46+
// In case it's not a valid format the middleware is skipped without affecting next ones
47+
return next();
48+
}
4649

47-
Object.values(UtmParamEnum).forEach(utmKey => {
48-
if (urlParams.has(utmKey)) {
49-
if (
50-
options.forceIfPresent !== undefined &&
51-
options.forceIfPresent === true
52-
) {
53-
urlParams.delete(utmKey);
54-
} else {
55-
existingUtmParams = true;
56-
}
57-
}
58-
});
50+
const urlParams = url.searchParams;
51+
let existingUtmParams: boolean = false;
5952

60-
if (!existingUtmParams) {
61-
for (const [utmKey, utmValue] of Object.entries(options.params)) {
62-
urlParams.set(utmKey, utmValue);
53+
Object.values(UtmParamEnum).forEach(utmKey => {
54+
if (urlParams.has(utmKey)) {
55+
if (
56+
options.forceIfPresent !== undefined &&
57+
options.forceIfPresent === true
58+
) {
59+
urlParams.delete(utmKey);
60+
} else {
61+
existingUtmParams = true;
6362
}
6463
}
64+
});
6565

66-
properties.href = url.toString();
67-
} catch (err) {
68-
// In case it's not a valid format the middleware is skipped without affecting next ones
66+
if (!existingUtmParams) {
67+
for (const [utmKey, utmValue] of Object.entries(options.params)) {
68+
urlParams.set(utmKey, utmValue);
69+
}
6970
}
7071

72+
properties.href = url.toString();
73+
7174
next();
7275
};
7376
}

0 commit comments

Comments
 (0)