Skip to content

Commit

Permalink
[full-ci] Webfinger redirect app (#8884)
Browse files Browse the repository at this point in the history
  • Loading branch information
kulmann authored Apr 26, 2023
1 parent 663951e commit 22d42b3
Show file tree
Hide file tree
Showing 14 changed files with 4,476 additions and 4,516 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/enhancement-webfinger-app
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Webfinger redirect app

We've added an app with the name `webfinger` which queries the oCIS webfinger service for the url of the oCIS instance of the user and performs a redirect. This app is not meant to be used in a standard deployment in its current state. It only uses web and its extension system as a platform. In the future this will become a multi tenancy select.

https://github.com/owncloud/web/issues/8883
https://github.com/owncloud/web/pull/8884
2 changes: 1 addition & 1 deletion dev/docker/ocis.web.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
],
"contextHelpersReadMore": true
},
"apps": ["files", "text-editor", "pdf-viewer", "search", "external", "admin-settings"],
"apps": ["files", "text-editor", "pdf-viewer", "search", "external", "admin-settings", "webfinger"],
"external_apps": [
{
"id": "preview",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"serve": "SERVER=true pnpm build:w",
"test:e2e:cucumber": "NODE_TLS_REJECT_UNAUTHORIZED=0 cucumber-js --profile=e2e -f json:tests/e2e/cucumber/report/cucumber_report.json",
"test:unit": "NODE_OPTIONS=--unhandled-rejections=throw jest --config ./tests/unit/config/jest.config.ts",
"licenses:check": "license-checker-rseidelsohn --summary --relativeLicensePath --onlyAllow 'Python-2.0;Apache*;Apache License, Version 2.0;Apache-2.0;Apache 2.0;Artistic-2.0;BSD;BSD-3-Clause;CC-BY-3.0;CC-BY-4.0;CC0-1.0;ISC;MIT;MPL-2.0;Public Domain;Unicode-TOU;Unlicense;WTFPL' --excludePackages '@ownclouders/babel-preset;@ownclouders/eslint-config;@ownclouders/prettier-config;@ownclouders/tsconfig;@ownclouders/web-client;@ownclouders/web-pkg;draw-io;external;web-app-files;text-editor;preview;@ownclouders/design-system;pdf-viewer;web-app-search;admin-settings;web-runtime'",
"licenses:check": "license-checker-rseidelsohn --summary --relativeLicensePath --onlyAllow 'Python-2.0;Apache*;Apache License, Version 2.0;Apache-2.0;Apache 2.0;Artistic-2.0;BSD;BSD-3-Clause;CC-BY-3.0;CC-BY-4.0;CC0-1.0;ISC;MIT;MPL-2.0;Public Domain;Unicode-TOU;Unlicense;WTFPL' --excludePackages '@ownclouders/babel-preset;@ownclouders/eslint-config;@ownclouders/prettier-config;@ownclouders/tsconfig;@ownclouders/web-client;@ownclouders/web-pkg;draw-io;external;web-app-files;text-editor;preview;@ownclouders/design-system;pdf-viewer;web-app-search;admin-settings;webfinger;web-runtime'",
"licenses:csv": "license-checker-rseidelsohn --relativeLicensePath --csv --out ./third-party-licenses/third-party-licenses.csv",
"licenses:save": "license-checker-rseidelsohn --relativeLicensePath --out /dev/null --files ./third-party-licenses/third-party-licenses",
"vite": "vue-demi-fix && pnpm vite:ocis",
Expand Down
9 changes: 9 additions & 0 deletions packages/web-app-webfinger/l10n/.tx/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[main]
host = https://www.transifex.com

[o:owncloud-org:p:owncloud-web:r:webfinger]
file_filter = locale/<lang>/LC_MESSAGES/app.po
minimum_perc = 0
source_file = template.pot
source_lang = en
type = PO
1 change: 1 addition & 0 deletions packages/web-app-webfinger/l10n/translations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
13 changes: 13 additions & 0 deletions packages/web-app-webfinger/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "web-app-webfinger",
"version": "0.0.0",
"private": true,
"description": "ownCloud webfinger resolver",
"license": "AGPL-3.0",
"peerDependencies": {
"design-system": "workspace:@ownclouders/design-system@*",
"web-app-webfinger": "workspace:*",
"web-client": "workspace:@ownclouders/web-client@*",
"web-pkg": "workspace:@ownclouders/web-pkg@*"
}
}
2 changes: 2 additions & 0 deletions packages/web-app-webfinger/src/discovery/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './types'
export * from './webfingerDiscovery'
5 changes: 5 additions & 0 deletions packages/web-app-webfinger/src/discovery/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface OwnCloudServer {
rel: string
href: string
titles?: Record<string, string>
}
28 changes: 28 additions & 0 deletions packages/web-app-webfinger/src/discovery/webfingerDiscovery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { OwnCloudServer } from 'web-app-webfinger/src/discovery/types'
import { ClientService } from 'web-pkg'
import { urlJoin } from 'web-client/src/utils'

interface OwnCloudInstancesResponse {
subject: string
links: OwnCloudServer[]
}

const OWNCLOUD_REL = 'http://webfinger.owncloud/rel/server-instance'

export class WebfingerDiscovery {
private serverUrl: string
private clientService: ClientService

constructor(serverUrl: string, clientService: ClientService) {
this.serverUrl = serverUrl
this.clientService = clientService
}

public async discoverOwnCloudServers(): Promise<OwnCloudServer[]> {
const client = this.clientService.httpAuthenticated
const url =
urlJoin(this.serverUrl, '.well-known', 'webfinger') + `?resource=${encodeURI(this.serverUrl)}`
const response: OwnCloudInstancesResponse = (await client.get(url)).data
return response.links.filter((o) => o.rel === OWNCLOUD_REL)
}
}
40 changes: 40 additions & 0 deletions packages/web-app-webfinger/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import translations from '../l10n/translations.json'
import Resolve from './views/Resolve.vue'

// just a dummy function to trick gettext tools
function $gettext(msg) {
return msg
}

const appInfo = {
name: $gettext('Webfinger'),
id: 'webfinger',
icon: 'fingerprint',
isFileEditor: false
}

const routes = () => [
{
name: 'webfinger-root',
path: '/',
redirect: () => {
return { name: 'webfinger-resolve' }
}
},
{
path: '/resolve',
name: 'webfinger-resolve',
component: Resolve,
meta: {
authContext: 'user',
title: $gettext('Resolve destination'),
entryPoint: true
}
}
]

export default {
appInfo,
routes,
translations
}
93 changes: 93 additions & 0 deletions packages/web-app-webfinger/src/views/Resolve.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<template>
<main
class="webfinger-resolve oc-height-viewport oc-flex oc-flex-column oc-flex-center oc-flex-middle"
>
<h1 class="oc-invisible-sr" v-text="pageTitle" />
<div class="oc-card oc-card-body oc-text-center oc-width-large">
<template v-if="hasError">
<h2 key="webfinger-resolve-error">
<span v-text="$gettext('Sorry!')" />
</h2>
<p v-text="$gettext('Something went wrong.')" />
<p v-text="$gettext('We could not resolve the destination.')" />
</template>
<template v-else>
<h2 key="webfinger-resolve-loading">
<span v-text="$gettext('One moment please…')" />
</h2>
<p v-text="$gettext('You are being redirected.')" />
</template>
</div>
</main>
</template>

<script lang="ts">
import { computed, defineComponent, ref, unref, watch } from 'vue'
import { useClientService, useConfigurationManager, useLoadingService, useRouteMeta } from 'web-pkg'
import { OwnCloudServer, WebfingerDiscovery } from 'web-app-webfinger/src/discovery'
import { useGettext } from 'vue3-gettext'
export default defineComponent({
name: 'WebfingerResolve',
setup() {
const configurationManager = useConfigurationManager()
const clientService = useClientService()
const loadingService = useLoadingService()
const { $gettext } = useGettext()
const title = useRouteMeta('title', '')
const pageTitle = computed(() => {
return $gettext(unref(title))
})
const ownCloudServers = ref<OwnCloudServer[]>([])
const hasError = ref(false)
const webfingerDiscovery = new WebfingerDiscovery(configurationManager.serverUrl, clientService)
loadingService.addTask(async () => {
try {
const servers = await webfingerDiscovery.discoverOwnCloudServers()
ownCloudServers.value = servers
if (servers.length === 0) {
hasError.value = true
}
} catch (e) {
console.error(e)
hasError.value = true
}
})
watch(ownCloudServers, (instances) => {
if (instances.length === 0) {
return
}
// we can't deal with multi-instance results. just pick the first one for now.
window.location.href = ownCloudServers.value[0].href
})
return {
pageTitle,
ownCloudInstances: ownCloudServers,
hasError
}
}
})
</script>

<style lang="scss">
.webfinger-resolve {
.oc-card {
background: var(--oc-color-background-highlight);
border-radius: 15px;
&-body {
h2 {
margin-top: 0;
}
p {
font-size: var(--oc-font-size-large);
}
}
}
}
</style>

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function useAppDocumentTitle({

const titleSegments = computed(() => {
const baseTitle =
basename(unref(unref(currentFileContext).fileName)) ||
basename(unref(unref(currentFileContext)?.fileName)) ||
$gettext((unref(currentRoute)?.meta?.title as string) || '')
const meta = unref(unref(appMeta).applicationMeta)

Expand Down
7 changes: 6 additions & 1 deletion packages/web-runtime/src/container/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,12 @@ export const announceDefaults = ({
defaultExtensionId = appIds[0]
}

const route = store.getters.getNavItemsByExtension(defaultExtensionId)[0]?.route
let route = router.getRoutes().find((r) => {
return r.path.startsWith(`/${defaultExtensionId}`) && r.meta?.entryPoint === true
})
if (!route) {
route = store.getters.getNavItemsByExtension(defaultExtensionId)[0]?.route
}
if (route) {
router.addRoute({
path: '/',
Expand Down
Loading

0 comments on commit 22d42b3

Please sign in to comment.