aboutsummaryrefslogtreecommitdiff
path: root/vnext/server/middleware
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2024-08-07 18:51:24 +0300
committerGravatar Vitaly Takmazov2024-08-07 20:02:02 +0300
commit1dd0547e3fd8d4cacc125def5800c9019dd72cef (patch)
tree553bf65cbb873b117dbedf7f00ff905192314959 /vnext/server/middleware
parent0ac9aa79aeb618a18d0e5032059c6d0dbc80ae17 (diff)
vnext: `releases` middleware
* Help android app to find upgrade path
Diffstat (limited to 'vnext/server/middleware')
-rw-r--r--vnext/server/middleware/android.js43
-rw-r--r--vnext/server/middleware/android.spec.js37
-rw-r--r--vnext/server/middleware/legacy.json142
3 files changed, 222 insertions, 0 deletions
diff --git a/vnext/server/middleware/android.js b/vnext/server/middleware/android.js
new file mode 100644
index 00000000..ae5f8fe8
--- /dev/null
+++ b/vnext/server/middleware/android.js
@@ -0,0 +1,43 @@
+import debug from 'debug'
+var log = debug('android')
+
+import * as legacy_data from './legacy.json'
+
+const releases_url = 'https://api.github.com/repos/Juick/Juick-Android/releases'
+
+/**
+ * Return android releases
+ * @type {import('express').RequestParamHandler}
+ */
+const releases = async (req, res) => {
+ let agent = req.headers['user-agent'] || 'unknown'
+ let android_version = parse_agent_android_sdk_version(agent)
+ log(`releases request from ${android_version || agent}`)
+ if (android_version > 0) {
+ if (is_legacy_android(android_version)) {
+ log('responding with legacy stub')
+ return res.json([legacy_data])
+ } else {
+ log('redirecting to Github')
+ return res.redirect(releases_url)
+ }
+ }
+ return res.json([])
+}
+
+const parse_agent_android_sdk_version = (agent = '') => {
+ let version = agent.split(' ', 3)
+ let is_android_app = version.length == 3 && version[2].startsWith('Android')
+ if (is_android_app) {
+ let android_version = version[2].split('/')
+ let is_valid_version = android_version.length == 2
+ return is_valid_version ? +(android_version[1]) : NaN
+ }
+ return NaN
+}
+
+const is_legacy_android = (version) => {
+ return version < 24
+}
+
+export default releases
diff --git a/vnext/server/middleware/android.spec.js b/vnext/server/middleware/android.spec.js
new file mode 100644
index 00000000..448714ac
--- /dev/null
+++ b/vnext/server/middleware/android.spec.js
@@ -0,0 +1,37 @@
+import request from 'supertest'
+import express from 'express'
+
+import releases from './android'
+
+const app = express()
+app.get('/releases', releases)
+
+describe('Releases helper', () => {
+ it('Should respond with empty array to unknown user agents', async () => {
+ return request(app)
+ .get('/releases')
+ .expect(200)
+ .then(response => {
+ expect(response.body).toStrictEqual([])
+ })
+ })
+ it('Should respond with a single legacy version data to old Android app', async () => {
+ return request(app)
+ .get('/releases')
+ .set('User-Agent', 'Juick/100 okhttp/3.12 Android/19')
+ .expect(200)
+ .then(response => {
+ expect(response.body.length).toBe(1)
+ expect(response.body[0].name).toBe('3.1.216')
+ })
+ })
+ it('Should redirect to Github when Android version is ok', async () => {
+ return request(app)
+ .get('/releases')
+ .set('User-Agent', 'Juick/100 okhttp/3.12 Android/24')
+ .expect(302)
+ .then(response => {
+ expect(response.redirect).toBe(true)
+ })
+ })
+})
diff --git a/vnext/server/middleware/legacy.json b/vnext/server/middleware/legacy.json
new file mode 100644
index 00000000..840708e6
--- /dev/null
+++ b/vnext/server/middleware/legacy.json
@@ -0,0 +1,142 @@
+{
+ "url": "https://api.github.com/repos/juick/Juick-Android/releases/164308344",
+ "assets_url": "https://api.github.com/repos/juick/Juick-Android/releases/164308344/assets",
+ "upload_url": "https://uploads.github.com/repos/juick/Juick-Android/releases/164308344/assets{?name,label}",
+ "html_url": "https://github.com/juick/Juick-Android/releases/tag/v3.1.216",
+ "id": 164308344,
+ "author": {
+ "login": "vitalyster",
+ "id": 1052407,
+ "node_id": "MDQ6VXNlcjEwNTI0MDc=",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1052407?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/vitalyster",
+ "html_url": "https://github.com/vitalyster",
+ "followers_url": "https://api.github.com/users/vitalyster/followers",
+ "following_url": "https://api.github.com/users/vitalyster/following{/other_user}",
+ "gists_url": "https://api.github.com/users/vitalyster/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/vitalyster/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/vitalyster/subscriptions",
+ "organizations_url": "https://api.github.com/users/vitalyster/orgs",
+ "repos_url": "https://api.github.com/users/vitalyster/repos",
+ "events_url": "https://api.github.com/users/vitalyster/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/vitalyster/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOADJkWc4JyyV4",
+ "tag_name": "v3.1.216",
+ "target_commitish": "master",
+ "name": "3.1.216",
+ "draft": false,
+ "prerelease": true,
+ "created_at": "2024-07-07T19:47:32Z",
+ "published_at": "2024-07-07T19:51:29Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/juick/Juick-Android/releases/assets/178215973",
+ "id": 178215973,
+ "node_id": "RA_kwDOADJkWc4Kn1wl",
+ "name": "Juick-free-v3.1.216.apk",
+ "label": null,
+ "uploader": {
+ "login": "vitalyster",
+ "id": 1052407,
+ "node_id": "MDQ6VXNlcjEwNTI0MDc=",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1052407?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/vitalyster",
+ "html_url": "https://github.com/vitalyster",
+ "followers_url": "https://api.github.com/users/vitalyster/followers",
+ "following_url": "https://api.github.com/users/vitalyster/following{/other_user}",
+ "gists_url": "https://api.github.com/users/vitalyster/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/vitalyster/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/vitalyster/subscriptions",
+ "organizations_url": "https://api.github.com/users/vitalyster/orgs",
+ "repos_url": "https://api.github.com/users/vitalyster/repos",
+ "events_url": "https://api.github.com/users/vitalyster/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/vitalyster/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 7807858,
+ "download_count": 2,
+ "created_at": "2024-07-07T19:51:12Z",
+ "updated_at": "2024-07-07T19:51:25Z",
+ "browser_download_url": "https://github.com/juick/Juick-Android/releases/download/v3.1.216/Juick-free-v3.1.216.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/juick/Juick-Android/releases/assets/178215894",
+ "id": 178215894,
+ "node_id": "RA_kwDOADJkWc4Kn1vW",
+ "name": "Juick-google-v3.1.216.apk",
+ "label": null,
+ "uploader": {
+ "login": "vitalyster",
+ "id": 1052407,
+ "node_id": "MDQ6VXNlcjEwNTI0MDc=",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1052407?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/vitalyster",
+ "html_url": "https://github.com/vitalyster",
+ "followers_url": "https://api.github.com/users/vitalyster/followers",
+ "following_url": "https://api.github.com/users/vitalyster/following{/other_user}",
+ "gists_url": "https://api.github.com/users/vitalyster/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/vitalyster/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/vitalyster/subscriptions",
+ "organizations_url": "https://api.github.com/users/vitalyster/orgs",
+ "repos_url": "https://api.github.com/users/vitalyster/repos",
+ "events_url": "https://api.github.com/users/vitalyster/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/vitalyster/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 8421195,
+ "download_count": 7,
+ "created_at": "2024-07-07T19:50:49Z",
+ "updated_at": "2024-07-07T19:51:04Z",
+ "browser_download_url": "https://github.com/juick/Juick-Android/releases/download/v3.1.216/Juick-google-v3.1.216.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/juick/Juick-Android/releases/assets/178215877",
+ "id": 178215877,
+ "node_id": "RA_kwDOADJkWc4Kn1vF",
+ "name": "Juick-huawei-v3.1.216.apk",
+ "label": null,
+ "uploader": {
+ "login": "vitalyster",
+ "id": 1052407,
+ "node_id": "MDQ6VXNlcjEwNTI0MDc=",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1052407?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/vitalyster",
+ "html_url": "https://github.com/vitalyster",
+ "followers_url": "https://api.github.com/users/vitalyster/followers",
+ "following_url": "https://api.github.com/users/vitalyster/following{/other_user}",
+ "gists_url": "https://api.github.com/users/vitalyster/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/vitalyster/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/vitalyster/subscriptions",
+ "organizations_url": "https://api.github.com/users/vitalyster/orgs",
+ "repos_url": "https://api.github.com/users/vitalyster/repos",
+ "events_url": "https://api.github.com/users/vitalyster/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/vitalyster/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 8275073,
+ "download_count": 3,
+ "created_at": "2024-07-07T19:50:27Z",
+ "updated_at": "2024-07-07T19:50:41Z",
+ "browser_download_url": "https://github.com/juick/Juick-Android/releases/download/v3.1.216/Juick-huawei-v3.1.216.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/juick/Juick-Android/tarball/v3.1.216",
+ "zipball_url": "https://api.github.com/repos/juick/Juick-Android/zipball/v3.1.216",
+ "body": "* Bugfixes and performance improvements"
+}