chrome.downloads.download never starts, but no errors - google-chrome

I'm trying to create a Chrome ext that uses the chrome.downloads API. But it doesn't seem to... do anything. First time Chrome developing so I'm a bit unfamiliar with the environment, but no one else online seems to have this problem.
Searching for the issue, I've minimized my code to the following (using the jQuery code as a test download, but have tried many others):
chrome.downloads.download({
url: "https://code.jquery.com/jquery-3.6.0.min.js",
}, (dlid) => {
chrome.downloads.search({id: dlid}, (dl) => {
console.log(dl[0]);
});
});
This results in the following DownloadItem being printed in the console:
byExtensionId: [redacted for privacy]
byExtensionName: [redacted for privacy]
bytesReceived: 0
canResume: false
danger: "safe"
exists: true
fileSize: 0
filename: ""
finalUrl: "https://code.jquery.com/jquery-3.6.0.min.js"
id: 2675
incognito: false
mime: "application/javascript"
paused: false
referrer: ""
startTime: "2021-09-04T09:18:02.401Z"
state: "in_progress"
totalBytes: 0
url: "https://code.jquery.com/jquery-3.6.0.min.js"
But the file doesn't download, nor does anything happen to indicate even an attempt at it. Continued readings of the DownloadItem always gives the same result: stating that the download is in progress and 0 bytes has been downloaded so far. And nothing else on my system gives any indication that the file is being downloaded. But never does it result in any errors - instead it just sits seemingly idling.
Here's what I've ruled out to be the cause so far:
Permission is declared in manifest.json: "permissions": [..., "downloads", ...]. Removing it and running the same code throws errors.
Context is correct, this is not run in a content script. Trying to do so throws errors.
Playing around with any of the DownloadOptions parameters has no effect at all. DownloadOptions.saveAs opens no dialog, and DownloadOptions.filename has no effect on the DownloadItem.filename which is always an empty string.
I've tried many other download targets, both different domains and different filetypes. The resulting mime parameter updates according to the URL extension, but otherwise it creates the same error-free perpetual idling.
I've even tried fake URLs with the same outcome - invalid URL syntaxes throws errors, but nonexistent URLs just gives the same idle result.
There's no evident Internet connectivity issues with my system, and I don't use any proxy or VPN.
Running it on another machine, albeit with the same Chrome user login and the same Internet connection. Same result.

Related

AASA - Apple App Site Association - Not working

I have been having a long and frustrating experience trying to get AASA to work for webcredentials. My goal here is to allow usernames and passwords to be stored in the iOS keychain.
I did have this working on a root domain the other week but it is not sufficient for my scenario as I will explain. It didn't work for me straight away I have to say but it eventually started working after a clean build so I thought this was the issue then but now I am not so sure.
I am using Expo with EAS build. We have a multi-tenant application. From a single codebase we deploy to multiple apps in the store. All are on the same team ID but they are separate applications and use separate credentials, nothing is shared.
I am confident my apps textContentType of username and password on my TextFields is correct as this has not changed from when I managed to get it working originally and I have checked it countless times.
Expectation
For the "Save Password" prompt to be displayed after login. What I have noticed however is when going to store a password manually using "add password" via iCloudKeychain from the keyboard accessory this does accurately show the correct "TENANT_SUBDOMAIN.example.com". I find this confusing.
Goal Scenario
I am hosting a site on Netlify. I have it setup to support wildcard subdomains with a LetsEncrypt provisioned wildcard SSL certificate. I then have edge functions which change the content of my index.html and apple-app-site-association file dynamically based on the requested subdomain.
I have added the Associated Domains capability to my provisioning profile.
I am using the latest Expo 47 and EAS build. I have added in the appropriate associated domains configuration and I can see this when introspecting my entitlements under com.apple.developer.associated-domains and it is correct.
I am using TestFlight for testing. I am doing a --clean-build on EAS every time and I also increase the runtime version. I have also tried manually refreshing credentials outside of the build process which does this automatically. This must be using the correct provisioning profile otherwise I would get a build failure as the requested entitlements wouldn't match.
The AASA file is currently hosted just in the .well-known directory. I have tried using the root and also tried using both. There are no redirects taking place.
I am aware the AASA file is pulled on application installation and update. I repeatedly remove the apps and then reboot my phone in an attempt to reset any device caches.
The content-type of the file is application/json and I have confirmed this using developer tools in the browser.
There is no robots.txt or anything blocking the request from an infrastructure perspective. There are no additional firewalls or geo restricted access as I am just using plain Netlify to host this, nothing fancy.
I am confident the Team ID and bundle IDs are correct in the AASA file.
I remove the content-length header in the Edge function so it is correctly calculated by the network instead and I have confirmed this using curl.
When I check the file using https://app-site-association.cdn-apple.com/a/v1/site.example.com Apple has the correct file cached on it's CDN so I would expect it to work.
I added in an applinks section so I could use the Apple App Search API validation tool and the Branch.io AASA verification tool to verify correctness. Branch.io says the file is fine and Apple says it's fine also but because the App has not been deployed to the store yet I see Error no apps with domain entitlements. From what I can tell this is normal in development and makes sense as it uses the current released version of the app to verify the deep link configuration. So to me this means Apple can parse the file correctly.
When I stream my device console logs; on install I can see the AASA requesting the correct domains. I see no errors on swcd I just see the Beginning data task AASA-XXXX with the correct domains.
When I run Charles proxy on my phone with a verified SSL installation (also reinstalled a few times now) I do not see quite what I would expect - but the device logs seem to imply it is doing the correct thing. When I view the app-site-association... URL requests in Charles there is one per application install which is correct. The request is marked as Unknown and when I look at the request the host is shown but as you would expect from SSL I see no path. The info says METHOD: CONNECT with Error - Input Error: EOF. This is the only error I see, I am not sure if it is a red herring and something to do with Charles. Given the error as you expect there is no body in the request or response. It is worth noting in general testing I have no VPN enabled and I have do not have Private Relay enabled in my iOS settings.
When I perform a sysdiagnose I see the following at the timestamp in my console log in the swcutil_show.txt device log. This looks correct in comparison to other apps webcredentials and applinks services I see there and I see no errors:
Service: webcredentials
App ID: MYTEAMID.com.cf.example.b2c.ios
App Version: 1.0
App PI: <LSPersistentIdentifier 0x141816200> { v = 0, t = 0x8, u = 0x1e7c, db = 0094F7C4-3078-41A2-A33E-79D5A62C80A6, {length = 8, bytes = 0x7c1e000000000000} }
Domain: CORRECT_SUBDOMAIN.example.app
User Approval: unspecified
Site/Fmwk Approval: approved
Flags:
Last Checked: 2022-12-09 14:14:32 +0000
Next Check: 2022-12-14 14:03:00 +0000
Service: applinks
App ID: MYTEAMID.com.cf.example.b2c.ios
App Version: 1.0
App PI: <LSPersistentIdentifier 0x13fd38d00> { v = 0, t = 0x8, u = 0x219c, db = 0094F7C4-3078-41A2-A33E-79D5A62C80A6, {length = 8, bytes = 0x9c21000000000000} }
Domain: CORRECT_SUBDOMAIN.example.app
Patterns: {"/":"*"}
User Approval: unspecified
Site/Fmwk Approval: approved
Flags:
Last Checked: 2022-12-13 13:13:23 +0000
Next Check: 2022-12-18 13:01:51 + 0000
At end of file:
MYTEAMID.com.cf.example.b2c.ios: 8 bytes
(This seems correct for all apps)
Other Scenario
I have tried setting this up using an apex on another domain which hasn't been seen before by Apple. I have tried using a subdomain with a root domain serving the same content and I have tried the subdomain and root domain on their own. I have also tried not using the Edge functions and having static files but to no avail.
When I do this I ensure I wait for the Apple CDN to catch up and remove/add entries prior to deleting the apps, rebooting my device, and reinstalling to test.
AASA File
AASA content comes back with the correct payload and Content-Type: application/json and Content-Length headers, both from Apples CDN and the origin. When I had this somehow working in my initial test it was on a root domain and I did not have an applinks section, this was only added so I could use the verification tools for universal links.
I am not sending back different content or duplicated content and I block the www subdomain - I have also tried it with a www subdomain for the record.
{
"applinks": {
"details": [
{
"appIDs": [
"MYTEAMID.com.cf.example.b2c.ios"
],
"components": [
{
"#": "no_universal_links",
"exclude": true,
"comment": "Matches any URL with a fragment that equals no_universal_links and instructs the system not to open it as a universal link."
}
]
}
]
},
"webcredentials": {
"apps": [
"MYTEAMID.com.cf.example.b2c.ios"
]
}
}
I have also tried this with the older format:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "MYTEAMID.com.cf.example.b2c.ios",
"paths": [
"*"
]
}
]
},
"webcredentials": {
"apps": [
"MYTEAMID.com.cf.example.b2c.ios"
]
}
}
associatedDomains iOS. expo config
associatedDomains: [
`webcredentials:${SUBDOMAIN}.example.app`,
`applinks:${SUBDOMAIN}.example.app`,
],
Help :)
I have been trying to get this to work for a long time now and I am completely out of ideas. If anybody has any suggestions I would really appreciate it. I am very confused how the devices request seems correct and the CDN content is correct but it is still not working. It's worth also reiterating that I need to have different subdomains for each tenant as the credentials must not be shared across apps so the keychain->domain association store must be different.
I am wondering if it's the LetsEncrypt wildcard SSL certificate but I wouldn't expect it to verify and for Apple to cache the file if this was the case. It seems very unlikely to me but it is the only thing I haven't tried at this point.
Many Thanks,
Mark

youtube-dl: Failed to parse JSON

I posted a question on this yesterday to the GitHub support page and it got flagged as a duplicate - the original answer is here. This issue doesn't automatically fix like it did for that user. Instead, it seems to come and go with no pattern, so I don't have a good way to replicate it. Some songs will work at one point in time, then they won't a couple minutes later.
Error:
[debug] Encodings: locale cp1252, fs utf-8, out UTF-8, pref cp1252
[debug] youtube-dl version 2020.09.20
[debug] Python version 3.7.8 (CPython) - Windows-10-10.0.19041-SP0
[youtube:search] query "iron man 3 song": Downloading page 1
[debug] exe versions: none
[debug] Proxy map: {}
ERROR: query "song name": Failed to parse JSON caused by JSONDecodeError('Expecting value: line 1 column 1 (char 0)')); please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see https://yt-dl.org/update on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
I get the issue when attempting to extract the data from the video. Here is a snippet of the code I am using:
ydlOps = {
'format': 'bestaudio/best',
'outtmpl': './%(title)s.webm',
'noplaylist': True,
'extractaudio': True,
'audioformat': 'webm',
'default_search': 'ytsearch1',
'quite': True,
'verbose':True,
'version': True
}
with youtube_dl.YoutubeDL(ydlOps) as downloader:
songData = downloader.extract_info(url, download=download)
I have changed the options, tried other options said to have worked, and nothing seems to make a difference. Some will work, then not, then they will again.
I think this is a youtube-dl bug. I wrote a parser for youtube searches and it also broke.
When looking previously at the response from youtube, all the JSON data was stored like this:
window["ytInitialData"] = {...}
So you just had to search through the server's response for the string 'window["ytInitialData"]' to find the relevant JSON and extract it. But now, youtube stores the JSON like this inside the html file sent by the server
var ytInitialData = {...}
This needs to be changed on youtube-dl's part when parsing the results.
What's strange is that sometimes youtube uses the previous version and sometimes it uses the current one. I think it's because the change in javascript is progressively being rolled out accross all youtube servers.
Also note that now, the line containing all the JSON ends with '; ' instead of just ';'. This might also require a change from youtube-dl.
You need to submit a pull request to youtube-dl or wait for somebody to fix it.

Chrome Web Store In-App Payments: Errors getting SKUs

I'm trying to get the SKUs available for a freemium Chrome Extension I'm developing.
I'm following all of the documentation here:
https://developer.chrome.com/webstore/payments-iap
...and I'm using the provided buy.js file, but it doesn't seem to work and the returned error messages are useless: "INVALID_RESPONSE_ERROR"
My code:
google.payments.inapp.getSkuDetails({
parameters: {env: 'prod'},
success: (r) => {
console.log(r);
},
failure: (err) => {
console.log(err);
},
});
Thoughts:
- Am I missing some permission in my manifest? I don't see any mention that it needs any additional ones.
Other StackOverflow questions have mentioned needing to proxy due to region issues. I'm in the states, shouldn't be an issue.
I've tried the above from both an options page and a popup - does it need to happen in a background page?
I'm pretty baffled. Any help is appreciated!
Thanks.
Updates:
The above works when released (in prod), but not locally
In prod you cannot buy your own thing (heads-up). It'll give you some stupid, meaningless error, but won't tell you that.
Still can't get this to work locally which means I have to test in prod.
If you need this to work locally, you must set the 'key' in your manifest.json file. When you reload it, it will show the same ID as the loaded extension from production.
Here are instructions on how to get the relevant key
If you debugging your extension in unpacked mode, you may need to set production "key" in your manifest.

Google Chrome not showing microphone permission prompt

I have a web application that uses the microphone for WebRTC through getUserMedia. I currently have this application running on multiple subdomains, like test.example.com, staging.example.com, production.example.com, etc.
On most of them, it works properly.
On one of the domains (test), I am unable to use the microphone. My code calls getUserMedia with a callback, but the callback is never executed, and the browser's permission prompt is never shown.
I have also reproduced this behavior using the Developer Tools console using the new Promise-based API:
navigator.mediaDevices.getUserMedia({audio: true, video: false}).then(console.log).catch(console.log)
(Yes, I know it does the same thing for then and catch, but it doesn't matter for this case.)
On the working site (stage, for example) here is the result in the console:
Promise {<pending>}
MediaStream {id: "RANDOM_CHARS", active: true, onaddtrack: null, onremovetrack: null, onactive: null, …}
On the non-working site, it only shows Promise {<pending>}, but the neither then nor catch logs anything because it never resolves either way.
I have found that if I go into the site settings (chrome://settings/content/siteDetails?site=https%3A%2F%2Ftest.example.com) and change Microphone to Allow, then I can refresh the page and it works properly. If I change it back to Ask, I get the same behavior again - that it doesn't ask.
This behavior is true about any site and any permission that I have tested - changing an Allowed permission back to Ask doesn't ask. However, on this particular test site, I had never before today tried to use it, so there's no reason it would have been set to Allow and then back to Ask to trigger that behavior.
In all these cases, navigator.permissions.query({name: "microphone"}).then(console.log) returns PermissionStatus {state: "prompt", onchange: null} as expected.
How can I get Chrome to prompt for microphone permission again?
You need a valid domain using https protocol in order to get Chrome to prompt for permissions.

typeahead prefetch weird behaviour

I'm using a very basic setup of Twitter's typeahead. I have 2 different search fields, hence the two typeahead initalizations.
Javascript:
$(document).ready(function() {
$('input.search-event').typeahead({
name: 'Events',
prefetch: '/media/json/events.json',
ttl: 0,
limit: 10
});
$('input.search-artist').typeahead({
name: 'Artists',
prefetch: '/media/json/artists.json',
ttl: 0,
limit: 10
});
});
Both events.json and artists.json are formatted as ["entry1", "entry2", "entry3", "..."].
I get different results in normal and incognito mode in Chrome. In normal mode it seems to be using an old json file that doesn't exist anymore (I've deleted it). In incognito mode it uses the correct json file, but it doesn't autosuggest the last item added to the json file. I was hoping ttl set to 0 would solve this problem but it doesn't. I've cleared my browser cache but that doesn't resolve the problem. I've read in other posts that I should clear my browser's localStorage but I don't really know how. There are no errors in the console log.
And I've just found out that typeahead is not showing anything at all in FF and Safari :-)
EDIT:
The results also seem to be depending on the name: value. Is that supposed to happen? For instance: if I change the name: value to 'test' typeahead doesn't work at all.
Typeahead does work in FF and in Safari. And the fact the without a name it doesn't work for you suggests (to me) that something in your json file is wrong, and that it didn't use to be the case, and that your browser is using a cached version.
Since name is the key to the cache, that might explain everything you're seeing:
Doesn't work in incognito mode, since the local storage isn't used in incognito, and there's something wrong with the json file itself.
Doesn't work with a different name, since a dataset with the different name isn't found in the cache (and again -- the json file is somehow bad).
Doesn't work in FF and in Safari -- same reason: the json is bad, and they don't have anything cached yet.
To debug, start with looking in the Developer Tools in Chrome (F12) under the network tab, and see the request and response to /media/json/artists.json, and make sure they are OK. Then make sure the content is indeed valid JSON.