@superfan-app/spotify-auth 0.1.77 → 0.1.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugin/build/index.js +31 -2
- package/plugin/src/index.ts +41 -5
package/package.json
CHANGED
package/plugin/build/index.js
CHANGED
|
@@ -111,8 +111,16 @@ const withSpotifyAndroidManifest = (config, props) => {
|
|
|
111
111
|
if (!mainActivity['intent-filter']) {
|
|
112
112
|
mainActivity['intent-filter'] = [];
|
|
113
113
|
}
|
|
114
|
-
// Check if we already have
|
|
115
|
-
|
|
114
|
+
// Check if we already have an intent filter covering the Spotify redirect.
|
|
115
|
+
// A broad scheme-only filter (no android:host) already covers superfan://callback,
|
|
116
|
+
// so we must treat it as sufficient to avoid registering two overlapping filters
|
|
117
|
+
// (which causes Android to show the app twice in the disambiguation dialog).
|
|
118
|
+
const hasSpotifyIntentFilter = mainActivity['intent-filter'].some((filter) => filter.data?.some((d) => {
|
|
119
|
+
const scheme = d.$?.['android:scheme'];
|
|
120
|
+
const host = d.$?.['android:host'];
|
|
121
|
+
// Matches if same scheme + matching host, OR same scheme with no host restriction
|
|
122
|
+
return scheme === props.scheme && (!host || host === callbackHost);
|
|
123
|
+
}));
|
|
116
124
|
if (!hasSpotifyIntentFilter) {
|
|
117
125
|
// Build the data element: android:host must be the hostname only (no path).
|
|
118
126
|
// If the callback has a path component (e.g. "auth/spotify"), add android:pathPrefix.
|
|
@@ -135,6 +143,26 @@ const withSpotifyAndroidManifest = (config, props) => {
|
|
|
135
143
|
return config;
|
|
136
144
|
});
|
|
137
145
|
};
|
|
146
|
+
const withSpotifyManifestPlaceholders = (config, props) => {
|
|
147
|
+
return (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
|
|
148
|
+
const { host: callbackHost, path: callbackPath } = parseCallback(props.callback);
|
|
149
|
+
const pathPattern = callbackPath ? callbackPath.replace(/\//g, '\\/') + '.*' : '.*';
|
|
150
|
+
const placeholderBlock = `manifestPlaceholders = [
|
|
151
|
+
redirectSchemeName: "${props.scheme}",
|
|
152
|
+
redirectHostName: "${callbackHost}",
|
|
153
|
+
redirectPathPattern: "${pathPattern}"
|
|
154
|
+
]`;
|
|
155
|
+
if (config.modResults.contents.includes('manifestPlaceholders')) {
|
|
156
|
+
// Replace existing block
|
|
157
|
+
config.modResults.contents = config.modResults.contents.replace(/manifestPlaceholders\s*=\s*\[[\s\S]*?\]/, placeholderBlock);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
// Inject into defaultConfig
|
|
161
|
+
config.modResults.contents = config.modResults.contents.replace(/defaultConfig\s*\{/, `defaultConfig {\n ${placeholderBlock}`);
|
|
162
|
+
}
|
|
163
|
+
return config;
|
|
164
|
+
});
|
|
165
|
+
};
|
|
138
166
|
// endregion
|
|
139
167
|
const withSpotifyAuth = (config, props) => {
|
|
140
168
|
// Ensure the config exists
|
|
@@ -147,6 +175,7 @@ const withSpotifyAuth = (config, props) => {
|
|
|
147
175
|
config = withSpotifyURLSchemes(config, props);
|
|
148
176
|
// Apply Android configurations
|
|
149
177
|
config = withSpotifyAndroidManifest(config, props);
|
|
178
|
+
config = withSpotifyManifestPlaceholders(config, props);
|
|
150
179
|
return config;
|
|
151
180
|
};
|
|
152
181
|
exports.default = (0, config_plugins_1.createRunOncePlugin)(withSpotifyAuth, pkg.name, pkg.version);
|
package/plugin/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// plugin/src/index.ts
|
|
2
2
|
|
|
3
|
-
import { type ConfigPlugin, createRunOncePlugin, withInfoPlist, withAndroidManifest, AndroidConfig } from '@expo/config-plugins'
|
|
3
|
+
import { type ConfigPlugin, createRunOncePlugin, withInfoPlist, withAndroidManifest, withAppBuildGradle, AndroidConfig } from '@expo/config-plugins'
|
|
4
4
|
import { SpotifyConfig } from './types.js'
|
|
5
5
|
|
|
6
6
|
const pkg = require('../../package.json');
|
|
@@ -128,12 +128,18 @@ const withSpotifyAndroidManifest: ConfigPlugin<SpotifyConfig> = (config, props)
|
|
|
128
128
|
mainActivity['intent-filter'] = [];
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
// Check if we already have
|
|
131
|
+
// Check if we already have an intent filter covering the Spotify redirect.
|
|
132
|
+
// A broad scheme-only filter (no android:host) already covers superfan://callback,
|
|
133
|
+
// so we must treat it as sufficient to avoid registering two overlapping filters
|
|
134
|
+
// (which causes Android to show the app twice in the disambiguation dialog).
|
|
132
135
|
const hasSpotifyIntentFilter = mainActivity['intent-filter'].some(
|
|
133
136
|
(filter: any) =>
|
|
134
|
-
filter.data?.some(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
filter.data?.some((d: any) => {
|
|
138
|
+
const scheme = d.$?.['android:scheme'];
|
|
139
|
+
const host = d.$?.['android:host'];
|
|
140
|
+
// Matches if same scheme + matching host, OR same scheme with no host restriction
|
|
141
|
+
return scheme === props.scheme && (!host || host === callbackHost);
|
|
142
|
+
})
|
|
137
143
|
);
|
|
138
144
|
|
|
139
145
|
if (!hasSpotifyIntentFilter) {
|
|
@@ -161,6 +167,35 @@ const withSpotifyAndroidManifest: ConfigPlugin<SpotifyConfig> = (config, props)
|
|
|
161
167
|
});
|
|
162
168
|
};
|
|
163
169
|
|
|
170
|
+
const withSpotifyManifestPlaceholders: ConfigPlugin<SpotifyConfig> = (config, props) => {
|
|
171
|
+
return withAppBuildGradle(config, (config) => {
|
|
172
|
+
const { host: callbackHost, path: callbackPath } = parseCallback(props.callback)
|
|
173
|
+
const pathPattern = callbackPath ? callbackPath.replace(/\//g, '\\/') + '.*' : '.*'
|
|
174
|
+
|
|
175
|
+
const placeholderBlock = `manifestPlaceholders = [
|
|
176
|
+
redirectSchemeName: "${props.scheme}",
|
|
177
|
+
redirectHostName: "${callbackHost}",
|
|
178
|
+
redirectPathPattern: "${pathPattern}"
|
|
179
|
+
]`
|
|
180
|
+
|
|
181
|
+
if (config.modResults.contents.includes('manifestPlaceholders')) {
|
|
182
|
+
// Replace existing block
|
|
183
|
+
config.modResults.contents = config.modResults.contents.replace(
|
|
184
|
+
/manifestPlaceholders\s*=\s*\[[\s\S]*?\]/,
|
|
185
|
+
placeholderBlock
|
|
186
|
+
)
|
|
187
|
+
} else {
|
|
188
|
+
// Inject into defaultConfig
|
|
189
|
+
config.modResults.contents = config.modResults.contents.replace(
|
|
190
|
+
/defaultConfig\s*\{/,
|
|
191
|
+
`defaultConfig {\n ${placeholderBlock}`
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return config
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
164
199
|
// endregion
|
|
165
200
|
|
|
166
201
|
const withSpotifyAuth: ConfigPlugin<SpotifyConfig> = (config, props) => {
|
|
@@ -179,6 +214,7 @@ const withSpotifyAuth: ConfigPlugin<SpotifyConfig> = (config, props) => {
|
|
|
179
214
|
|
|
180
215
|
// Apply Android configurations
|
|
181
216
|
config = withSpotifyAndroidManifest(config, props);
|
|
217
|
+
config = withSpotifyManifestPlaceholders(config, props);
|
|
182
218
|
|
|
183
219
|
return config;
|
|
184
220
|
};
|