FEATURE: Site settings for linking with iOS/Android native apps

- Adds support for iOS Universal Links via an `apple-app-site-association` endpoint

 Adds support for Google Digital Asset Links at the `.well-known/assetlinks.json` endpoint
This commit is contained in:
Penar Musaraj 2019-08-27 14:05:37 -04:00
parent 8e5a8d1d54
commit 5c02bfb000
5 changed files with 74 additions and 0 deletions

View File

@ -12,6 +12,16 @@ class MetadataController < ApplicationController
render template: "metadata/opensearch.xml"
end
def app_association_android
raise Discourse::NotFound unless SiteSetting.app_association_android.present?
render plain: SiteSetting.app_association_android, content_type: 'application/json'
end
def app_association_ios
raise Discourse::NotFound unless SiteSetting.app_association_ios.present?
render plain: SiteSetting.app_association_ios, content_type: 'application/json'
end
private
def default_manifest

View File

@ -1929,6 +1929,9 @@ en:
native_app_install_banner_android: "Displays DiscourseHub app banner on Android devices to regular users (trust level 1 and up)."
app_association_android: "Contents of <a href='/.well-known/assetlinks.json'>.well-known/assetlinks.json</a> endpoint, used for Google's Digital Asset Links API."
app_association_ios: "Contents of <a href='/apple-app-site-association'>apple-app-site-association</a> endpoint, used to create Universal Links between this site and iOS apps."
share_anonymized_statistics: "Share anonymized usage statistics."
auto_handle_queued_age: "Automatically handle records that are waiting to be reviewed after this many days. Flags will be ignored. Queued posts and users will be rejected. Set to 0 to disable this feature."

View File

@ -812,6 +812,8 @@ Discourse::Application.routes.draw do
get "offline.html" => "offline#index"
get "manifest.webmanifest" => "metadata#manifest", as: :manifest
get "manifest.json" => "metadata#manifest"
get ".well-known/assetlinks.json" => "metadata#app_association_android"
get "apple-app-site-association" => "metadata#app_association_ios", format: false
get "opensearch" => "metadata#opensearch", constraints: { format: :xml }
scope "/tags" do

View File

@ -1931,6 +1931,16 @@ uncategorized:
default: "iPad|iPhone"
hidden: true
app_association_android:
client: false
default: ""
textarea: true
app_association_ios:
client: false
default: ""
textarea: true
share_anonymized_statistics: true
auto_handle_queued_age:

View File

@ -101,4 +101,53 @@ RSpec.describe MetadataController do
expect(response.content_type).to eq('application/xml')
end
end
describe '#app_association_android' do
it 'returns 404 by default' do
get "/.well-known/assetlinks.json"
expect(response.status).to eq(404)
end
it 'returns the right output' do
SiteSetting.app_association_android = <<~EOF
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target" : { "namespace": "android_app", "package_name": "com.example.app",
"sha256_cert_fingerprints": ["hash_of_app_certificate"] }
}]
EOF
get "/.well-known/assetlinks.json"
expect(response.status).to eq(200)
expect(response.body).to include("hash_of_app_certificate")
expect(response.body).to include("com.example.app")
expect(response.content_type).to eq('application/json')
end
end
describe '#app_association_ios' do
it 'returns 404 by default' do
get "/apple-app-site-association"
expect(response.status).to eq(404)
end
it 'returns the right output' do
SiteSetting.app_association_ios = <<~EOF
{
"applinks": {
"apps": []
}
}
EOF
get "/apple-app-site-association"
expect(response.status).to eq(200)
expect(response.body).to include("applinks")
expect(response.content_type).to eq('application/json')
get "/apple-app-site-association.json"
expect(response.status).to eq(404)
end
end
end