Skip to content

Commit

Permalink
Fix query param handling in AuthService.signInCallback
Browse files Browse the repository at this point in the history
  • Loading branch information
dschmidt committed Apr 5, 2023
1 parent 3ccc421 commit 4306990
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 49 deletions.
6 changes: 4 additions & 2 deletions changelog/unreleased/bugfix-open-external-apps
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Bugfix: Open files in external app

We've fixed a bug that caused office documents not to be opened in app provider editors anymore.
We've fixed bugs that caused office documents not to be opened in app provider editors anymore.

https://github.com/owncloud/web/pull/8705
https://github.com/owncloud/web/issues/8695
https://github.com/owncloud/web/pull/8705
https://github.com/owncloud/web/issues/8773
https://github.com/owncloud/web/pull/8782
13 changes: 1 addition & 12 deletions packages/web-runtime/src/router/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { base, router } from './index'
import { RouteLocation, RouteParams, Router, RouteRecordNormalized } from 'vue-router'
import pick from 'lodash-es/pick'
import {
AuthContext,
authContextValues,
Expand All @@ -11,17 +10,7 @@ import {
export const buildUrl = (pathname) => {
const isHistoryMode = !!base
const baseUrl = new URL(window.location.href.split('#')[0])

// searchParams defines a set of search parameters which should be part of new url.
// The resulting querystring only contains the properties listed here.
const searchParams = new URLSearchParams(
pick(Object.fromEntries(new URLSearchParams(window.location.search).entries()), [
// needed for private links
'details'
])
).toString()

baseUrl.search = searchParams
baseUrl.search = ''

if (isHistoryMode) {
// in history mode we can't determine the base path, it must be provided by the document
Expand Down
18 changes: 3 additions & 15 deletions packages/web-runtime/src/services/auth/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
import { unref } from 'vue'
import { Ability } from 'web-pkg/src/utils'
import { Language } from 'vue3-gettext'
import pick from 'lodash-es/pick'

export class AuthService {
private clientService: ClientService
Expand Down Expand Up @@ -176,23 +175,12 @@ export class AuthService {
* Sign in callback gets called from the IDP after initial login.
*/
public async signInCallback() {
const currentQuery = unref(this.router.currentRoute).query

try {
await this.userManager.signinRedirectCallback(this.buildSignInCallbackUrl())

const redirectUrl = this.userManager.getAndClearPostLoginRedirectUrl()

// transportQuery defines a set of query parameters which should be part of router route replace.
// The resulting object only contains the properties listed here.
const transportQuery = pick(currentQuery, [
// needed for private links
'details'
])

const redirectRoute = this.router.resolve(this.userManager.getAndClearPostLoginRedirectUrl())
return this.router.replace({
path: redirectUrl,
query: transportQuery
path: redirectRoute.path,
...(redirectRoute.query && { query: redirectRoute.query })
})
} catch (e) {
console.warn('error during authentication:', e)
Expand Down
3 changes: 0 additions & 3 deletions packages/web-runtime/tests/unit/router/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ describe('buildUrl', () => {
${'https://localhost:9200/files/list/all'} | ${'/foo'} | ${'/login/foo'} | ${'https://localhost:9200/foo/login/foo'}
${'https://localhost:9200/files/list/all'} | ${'/'} | ${'/bar.html'} | ${'https://localhost:9200/bar.html'}
${'https://localhost:9200/files/list/all'} | ${'/foo'} | ${'/bar.html'} | ${'https://localhost:9200/foo/bar.html'}
${'https://localhost:9200/files/list/all?details=91953740'} | ${'/foo'} | ${'/bar.html'} | ${'https://localhost:9200/foo/bar.html?details=91953740'}
${'https://localhost:9200/files/list/all?details=91953740&unknown=87987987'} | ${'/foo'} | ${'/bar.html'} | ${'https://localhost:9200/foo/bar.html?details=91953740'}
${'https://localhost:9200/files/list/all?unknown=87987987'} | ${'/foo'} | ${'/bar.html'} | ${'https://localhost:9200/foo/bar.html'}
`('$path -> $expected', async ({ location, base, path, expected }) => {
delete window.location
window.location = new URL(location) as any
Expand Down
48 changes: 31 additions & 17 deletions packages/web-runtime/tests/unit/services/auth/authService.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,41 @@
import { AuthService } from 'web-runtime/src/services/auth/authService'
import { createRouter } from 'web-test-helpers/src'

describe('AuthService', () => {
describe('signInCallback', () => {
it.each([
[{ details: 'details' }, { details: 'details' }],
[{ details: 'details', unknown: 'unknown' }, { details: 'details' }],
[{ unknown: 'unknown' }, {}]
])('forwards only whitelisted query parameters: %s = %s', async (query, expected: any) => {
const authService = new AuthService()
const replace = jest.fn()
['/', '/', {}],
['/?details=sharing', '/', { details: 'sharing' }],
[
'/external?contextRouteName=files-spaces-personal&fileId=0f897576',
'/external',
{
contextRouteName: 'files-spaces-personal',
fileId: '0f897576'
}
]
])(
'parses query params and passes them explicitly to router.replace: %s => %s %s',
async (url, path, query: any) => {
const authService = new AuthService()

jest.replaceProperty(authService as any, 'userManager', {
signinRedirectCallback: jest.fn(),
getAndClearPostLoginRedirectUrl: jest.fn()
})
jest.replaceProperty(authService as any, 'userManager', {
signinRedirectCallback: jest.fn(),
getAndClearPostLoginRedirectUrl: () => url
})

jest.replaceProperty(authService as any, 'router', {
currentRoute: { query },
replace
})
await authService.signInCallback()
const router = createRouter()
const replaceSpy = jest.spyOn(router, 'replace')

expect(replace.mock.calls[0][0].query).toEqual(expected)
})
authService.initialize(null, null, null, router, null, null)

await authService.signInCallback()

expect(replaceSpy).toHaveBeenCalledWith({
path,
query
})
}
)
})
})

0 comments on commit 4306990

Please sign in to comment.