Universal link - The domain has some validation issue - ios

Im working on universal link to open the application while tap the url. I am using https server and done all the steps from apple (Apple Doc). But the apple universal link validator show below error,
Your file's 'content-type' header was not found or was not recognized.
The apple-app-site-association file successfully uploaded to server and the file be like below,
{
"applinks": {
"apps": [],
"details": [
{
"appID": "J2HBF9A3PZ.com.aors.speaku",
"paths": ["*","/"]
}
]
}
}
And apple said no need to sign the apple-app-site-association file whether the domain has https.
If the file is unsigned, it should have a Content-Type of
application/json. Otherwise, it should be application/pkcs7-mime.
So my query is how to mention the content type (application/json) in this apple-app-site-association file???
please help me on this. i don't know what it mean exactly.

I just solved this issue myself. I had to logon to my server and go to the directory where the apple-app-site-association file was. In this directory, I had a .htaccess file which I modified to include the following lines:
<Files "apple-app-site-association">
ForceType 'application/json'
</Files>
After doing this, the validation service stopped complaining about the Content-Type.
NOTES:
If you don't have a .htaccess file, you can just create one.
I presume the .htaccess file should be in the root of your site directory (which is where you would most likely have placed your apple-app-site-association file.

Wordpress website. Pasting this at the end of .htaccess actually worked for me:
Header set Content-type "application/pkcs7-mime"

This one fixed the content type validation in firebase.json file.
{
"hosting": {
"public": "public",
"headers": [
{
"source": "/.well-known/apple-app-site-association",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
}
],
"appAssociation": "NONE"
}
}

This syntax is what worked for me:
<FilesMatch "apple-app-site-association">
ForceType application/json
</FilesMatch>

Related

How to edit the apple-app-site-association file auto-generated by Firebase Dynamic Links?

Whenever I create a new url prefix using free Google-provided domain (for example, yourapp.page.link). The apple-app-site-association file gets automatically created at the respective https://yourapp.page.link/apple-app-site-association and https://yourapp.page.link/.well-known/apple-app-site-association.
The generated apple-app-site-association file looks something like:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "1234567890.com.example.ios",
"paths": [
"NOT /_/*",
"/*"
]
}
]
}
}
and it is redirecting all paths to my app.
I want to exclude certain paths that should not be handled by my app. I know I can do this by specifying “NOT ” in front of the path that i want to exclude in the paths array, but I just can't find a way to edit the auto-generated file.
I had a similar issue with dynamic links "hijacking" the links for email verification and password reset, forcing me to manually add exclude paths to the apple-app-site-association file. The only way forward I could find that seems to be working is to do the following:
Add your apple-app-site-association file to your public folder:
/public/apple-app-site-association (or whatever you have set as public folder)
/public/.well-known/apple-app-site-association
Add the following to the hosting section in your firebase.json (keep "appAssociation": "AUTO" or your dynamic links will stop working and you'll see an error message in the console.)
"headers": [
{
"source": "/.well-known/apple-app-site-association",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
},
{
"source": "/apple-app-site-association",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
}
]

How to serve apple-app-site-association file on /apple-app-site-association page in ReactJS

I'm having a lot of trouble with serving a apple-app-site-association file in ReactJS project.
I've searched a lot of GitHub issues pages (for ReactJS, Gatsby, and Angular), forums, and a lot of online communities, and it seems that I can't find a solution for this.
What I've tried is:
Adding the file into public/.well-known folder.
Adding a separate route via react-router on path "/apple-app-site-association" and returning an tag with file
Adding <link rel="apple-app-site-association" href="%PUBLIC_URL%/.well-known/apple-app-site-association"> into public/index.html
Testing through the "aasa-validator" returns:
Your file's 'content-type' header was not found or was not recognized.
Keep in mind that:
The apple-app-site-association JSON file must not have a .json file extension.
It has to be on "/apple-app-site-association" or "./well-known/apple-app-site-association" links on the website.
I can't use a redirect to another page/link.
Thanks in advance!
Ps. If it helps, I'm using a Heroku for deployment.
For NextJs
As discussed here, it is possible to server apple-app-site-association from NextJs.
Next.js uses the extension to automatically detect the content-type of the file. Since the file is extensionless, it's served as binary content—this should be compatible with Apple's verification.
If Apple requires specific headers, you can overwrite this type:
// next.config.js
module.exports = {
experimental: {
headers() {
return [
{
source: "/.well-known/apple-app-site-association",
headers: [{ key: "content-type", value: "application/json" }]
}
];
}
}
};
You can serve the file using React Router.
Put this in your index.js or App.js:
const reload = () => window.location.reload();
<Route path="/apple-app-site-association" onEnter={reload} />
More details here:
https://brainbank.cc/jamie/lessons/programming-react/serve-static-file-txt-html-via-react-router
several days have passed and I didn't find an answer or solution. (And I really hate to see an unanswered stackoverflow question when I'm searching for a solution)
I've talked to a lot of people and pretty much everyone said this is impossible. Reason for that is that ReactJS is unable to return JSON type of response upon client sending a GET request.
So we transfered the file onto the back-end side which is working perfectly.
tl;dr It's not possible.
For CRA:
The file apple-app-site-association should be added to the public folder or public/.well-known folder. This alone won't make it work. Because it is served with a content-type of application/octet-stream. To fix it, we should use a solution provided by the hosting provider.
For Firebase:
I am using Firebase for hosting my CRA app. So, for firebase, it is possible to specify the response headers for the path. The following gist shows how to do this. Make sure that the appAssociation should also be set to prevent firebase dynamic links from serving some other AASA file.
firebase.json config
{
"hosting": {
"public": "public",
"headers": [
{
"source": "/.well-known/apple-app-site-association",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
}
],
"appAssociation": "NONE"
}
}
If you're using Cloudfront in AWS you can create a custom Response Headers Policy:
We serve our CRA app using the npm serve CLI package. This is what we did to resolve the issue of serving our extension-less apple-app-site-association file.
The fix for this is to create the apple-app-site-association as apple-app-site-association.json inside your public/.well-known directory and then create a rewrite rule inside of a file in your public directory called serve.json. The contents of that file should look like this.
{
"rewrites": [
{
"source": "!.well-known/**",
"destination": "index.html"
},
{
"source": ".well-known/apple-app-site-association",
"destination": ".well-known/apple-app-site-association.json"
}
]
}
Then when you start your static file server, you don't use the -s or --single argument. You start it using the following command.
serve -c serve.json
The first item will send all requests that don't exist inside of .well-known to index.html, and the second rewrite will send requests for that specific URL to the apple-app-site-association.json file and assign a content-type: application/json header to it. All other files with file extensions should be served as normal, ignoring any rewrite rules.
Disclaimer: This is only applicable if you have an Nginx implementation.
I got stuck on this and couldn't figure out a way to add the apple site association file to the react code in any way.
However, I was able to solve the issue by looking outside the react box and inside my server configuration box i.e. Nginx.
Here are the steps:
In the server store the AASA or apple-app-site-association.json file in a particular location - I chose to store it at (had to create two certifications and ios directories)
/var/www/certificates/ios/
Now go to the sites-available folder
cd /etc/nginx/sites-available/
Here, you will find the file with your web app's Nginx configuration information.
Let's say, the name of my file was example-web-app, so open the file using vim with sudo privileges:
sudo vim mayank-web-app
Now inside this file, you need to find
location / {
Just above this line paste this code block
location /apple-app-site-association {
alias /var/www/certificates/ios/;
index apple-app-site-association.json
autoindex on; }
Now save the file and exit, by pressing esc and typing
wq!
Now check if the changes are valid by typing
sudo nginx -t
You should get this as output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
After this you will have to go to the sites-enabled directory
cd ../sites-enabled
9. Update the symlink here
sudo ln -s /etc/nginx/sites-available/example-web-app .
Now reload the nginx service
sudo service nginx reload
Now you can check this with two methods:
a. https://branch.io/resources/aasa-validator/#resultsbox.
b. https://example.com/apple-app-site-association
I has this problem using react/redux and Next.js
this is how I solved the issue
in my /static folder I put my apple-app-site-association
{
"webcredentials": {
"apps": ["12345431.com.app"]
},
"applinks": {
"apps": [],
"details": [
{
"appID": "12345431.com.app",
"paths": [ "*"]
}
}
]
}
}
I created a component called Apple AppleAssociation.jsx in that file I have
import React from 'react'
function AppleAssociation() {
return (
//path to apple app site association file
<>
<link rel="apple-app-site-association file" href="/static/apple-app-site-association" />
</>
)
}
export default AppleAssociation
and in my _app.jsx file I import that into my head
import React from 'react'
import Head from 'next/head'
import withRedux from 'next-redux-wrapper'
import App, { Container as NextContainer } from 'next/app'
import { Provider as ReduxProvider } from 'react-redux'
import {
AppleAssociation,
} from '../components/head'
import makeStore from '../lib/store'
class CustomApp extends App {
static async getInitialProps({ Component}) {
let pageProps = {}
return {
pageProps,
}
}
componentDidMount() {
}
render() {
const { Component, pageProps, session, store } = this.props
return (
<NextContainer>
<Head>
<meta
name="viewport"
content="width=device-width, initial-scale=1, minimal-ui"
/>
<AppleAssociation />
</Head>
<ReduxProvider store={store}>
<NextSeo config={seo} />
<Component {...pageProps} />
</ReduxProvider>
</NextContainer>
)
}
}
export default withRedux(makeStore)(CustomApp)
you can test this by using https://branch.io/resources/aasa-validator/#resultsbox
If you have any other redirects / rewrite rules make sure the apple-app-site-association re-write is placed before others.
For example this is with AWS Amplify for React JS:
[
{
"source": "/.well-known/apple-app-site-association",
"target": "/.well-known/apple-app-site-association.json",
"status": "200",
"condition": null
},
{
"source": "</^[^.]+$|\\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>",
"target": "/index.html",
"status": "200",
"condition": null
}
]
with the apple-app-site-association file placed as a JSON file here:
/public/.well-known/apple-app-site-association.json

Universal Linking Bad JSON

I have my apple-app-site-association uploaded correctly on the server. It's formatted as follows:
{
"activitycontinuation": {
"apps": [
"ASDF.com.company.appname"
]
},
"applinks": {
"apps": [],
"details": [
{
"appID": "ASDF.com.company.appname",
"paths": [ "/menu/*", "/menu/*/*", "/account/history", "/"]
}
]
}
}
My entitlements is set up correctly:
applinks:company-site.com
activitycontinuation:company-site.com
I've verified with Charles proxy on install the device fetches the correct file from the server.
When looking at the device log, I get the following error:
Bad apple-app-site-association JSON: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
I've ran the JSON through a linter and it came out fine. The server sends back Content-Type: application/json in the header. I'm testing on a physical device. I've tried typing the URLs manually in safari and clicking them through a text message. Does anyone see where the problem is?
I believe the first section of your apple-app-site-association is unnecessary and may be causing the validation error (Apple is pretty strict about this file). I haven't seen this in any other places — is there a particular reason you're including it?
Try this and see if it works better:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "ASDF.com.company.appname",
"paths": [ "/menu/*", "/menu/*/*", "/account/history", "/"]
}
]
}
}
Also note that Universal Links will never work when entered manually into Safari. See here for more info.

How to create apple-app-site-association file for Universal Linking in IOS 9?

I have some problem in creating apple-app-site-association file.I don't know how to create json file without json extentsion and have content type application/json for the same file.I want to use this file without any signing as it doesn't need in IOS 9 but I couldn't able to create the valid apple-app-site-association file.
I have setup everything on my app like associated domains,app delegate method,provisioning profiles.
Here is my code on the backend side:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "teamID.bundleID",
"paths": [ "*" ]
}
]
}
}
Another method is to use file match to match exactly your file and to enforce the required content-type:
add following lines to your .htaccess file:
<FilesMatch "^apple-app-site-association$">
ForceType application/json
</FilesMatch>
this worked for me.
Open your terminal and type
cd desktop
press return key and then type
touch apple-app-site-association
press return
a file is created without any extension
I added the following to the .htaccess file in the root folder. This is a bit rough, but it worked for me to return the file in application/json
RewriteRule ^apple-app-site-association$ - [env=apple:1]
Header set Content-type application/json env=apple
I was not able to make Universal Link work with iOS9 serving application/json yet. Let me know if you made i work.

The apple-app-site-association file format error

*I have error message from API Validation Tool from Apple*
**The apple-app-site-association file was found but it doesn’t follow the required format. Learn how to format the apple-app-site-association file.**
*My apple-app-site-association file:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TeamId.com.Company.AppName",
"paths": [
"/path1-*",
"/path2",
"/path3-*",
"/path4"
]
}
]
}
}
I saw this videos from WWDC 2015 "Seamless linking to your Apps" and "Introducing Search API" and read this App Search Programming Guide.
My website have an SSL certificate (from Authority certified) and my apple-app-site-association is inside https://www.mywebsite.com/apple-app-site-association
I don't know what is wrong with the file. I think syntax error can be but I cant see it.*
seems like you should replace TeamId.com.Company.AppName with your REAL TeamId and REAL bundle id.
Look at this one for exmaple
https://routes.tips/apple-app-site-association
It`s nor signed, but working and passing validation
Dears
There is one more issue about TeamID, especially more than one apps in one accout.
Please use the App IDs prefix into your appID of app-app-site-assiciation.

Resources