mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-06-06 01:21:39 -04:00
Adapt react-client to use the real backend API (#1545)
Co-authored-by: Philip Molares <philip.molares@udo.edu> Co-authored-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
3399ed2023
commit
26f90505ff
227 changed files with 4726 additions and 2310 deletions
80
src/pages/api/mock-backend/private/config.ts
Normal file
80
src/pages/api/mock-backend/private/config.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import type { Config } from '../../../../api/config/types'
|
||||
import { AuthProviderType } from '../../../../api/config/types'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../handler-utils/respond-to-matching-request'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
respondToMatchingRequest<Config>(HttpMethod.GET, req, res, {
|
||||
allowAnonymous: true,
|
||||
allowRegister: true,
|
||||
authProviders: [
|
||||
{
|
||||
type: AuthProviderType.LOCAL
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.LDAP,
|
||||
identifier: 'test-ldap',
|
||||
providerName: 'Test LDAP'
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.DROPBOX
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.FACEBOOK
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.GITHUB
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.GITLAB,
|
||||
identifier: 'test-gitlab',
|
||||
providerName: 'Test GitLab'
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.GOOGLE
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.OAUTH2,
|
||||
identifier: 'test-oauth2',
|
||||
providerName: 'Test OAuth2'
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.SAML,
|
||||
identifier: 'test-saml',
|
||||
providerName: 'Test SAML'
|
||||
},
|
||||
{
|
||||
type: AuthProviderType.TWITTER
|
||||
}
|
||||
],
|
||||
branding: {
|
||||
name: 'DEMO Corp',
|
||||
logo: '/mock-public/img/demo.png'
|
||||
},
|
||||
useImageProxy: false,
|
||||
specialUrls: {
|
||||
privacy: 'https://example.com/privacy',
|
||||
termsOfUse: 'https://example.com/termsOfUse',
|
||||
imprint: 'https://example.com/imprint'
|
||||
},
|
||||
version: {
|
||||
major: 2,
|
||||
minor: 0,
|
||||
patch: 0,
|
||||
commit: 'mock'
|
||||
},
|
||||
plantumlServer: 'https://www.plantuml.com/plantuml',
|
||||
maxDocumentLength: 1000000,
|
||||
iframeCommunication: {
|
||||
editorOrigin: process.env.NEXT_PUBLIC_EDITOR_ORIGIN ?? 'http://localhost:3001/',
|
||||
rendererOrigin: process.env.NEXT_PUBLIC_RENDERER_ORIGIN ?? 'http://127.0.0.1:3001/'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
18
src/pages/api/mock-backend/private/groups/_EVERYONE.ts
Normal file
18
src/pages/api/mock-backend/private/groups/_EVERYONE.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { GroupInfo } from '../../../../../api/group/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
respondToMatchingRequest<GroupInfo>(HttpMethod.GET, req, res, {
|
||||
name: '_EVERYONE',
|
||||
displayName: 'Everyone',
|
||||
special: true
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
18
src/pages/api/mock-backend/private/groups/_LOGGED_IN.ts
Normal file
18
src/pages/api/mock-backend/private/groups/_LOGGED_IN.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { GroupInfo } from '../../../../../api/group/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
respondToMatchingRequest<GroupInfo>(HttpMethod.GET, req, res, {
|
||||
name: '_LOGGED_IN',
|
||||
displayName: 'All registered users',
|
||||
special: true
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
18
src/pages/api/mock-backend/private/groups/hedgedoc-devs.ts
Normal file
18
src/pages/api/mock-backend/private/groups/hedgedoc-devs.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { GroupInfo } from '../../../../../api/group/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
respondToMatchingRequest<GroupInfo>(HttpMethod.GET, req, res, {
|
||||
name: 'hedgedoc-devs',
|
||||
displayName: 'HedgeDoc devs',
|
||||
special: true
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
44
src/pages/api/mock-backend/private/me/history.ts
Normal file
44
src/pages/api/mock-backend/private/me/history.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { HistoryEntry } from '../../../../../api/history/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
respondToMatchingRequest<HistoryEntry[]>(HttpMethod.GET, req, res, [
|
||||
{
|
||||
identifier: 'slide-example',
|
||||
title: 'Slide example',
|
||||
lastVisitedAt: '2020-05-30T15:20:36.088Z',
|
||||
pinStatus: true,
|
||||
tags: ['features', 'cool', 'updated']
|
||||
},
|
||||
{
|
||||
identifier: 'features',
|
||||
title: 'Features',
|
||||
lastVisitedAt: '2020-05-31T15:20:36.088Z',
|
||||
pinStatus: true,
|
||||
tags: ['features', 'cool', 'updated']
|
||||
},
|
||||
{
|
||||
identifier: 'ODakLc2MQkyyFc_Xmb53sg',
|
||||
title: 'Non existent',
|
||||
lastVisitedAt: '2020-05-25T19:48:14.025Z',
|
||||
pinStatus: false,
|
||||
tags: []
|
||||
},
|
||||
{
|
||||
identifier: 'l8JuWxApTR6Fqa0LCrpnLg',
|
||||
title: 'Non existent',
|
||||
lastVisitedAt: '2020-05-24T16:04:36.433Z',
|
||||
pinStatus: false,
|
||||
tags: ['agenda', 'HedgeDoc community', 'community call']
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
export default handler
|
21
src/pages/api/mock-backend/private/me/index.ts
Normal file
21
src/pages/api/mock-backend/private/me/index.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { LoginUserInfo } from '../../../../../api/me/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse): void => {
|
||||
respondToMatchingRequest<LoginUserInfo>(HttpMethod.GET, req, res, {
|
||||
username: 'mock',
|
||||
photo: '/mock-public/img/avatar.png',
|
||||
displayName: 'Mock User',
|
||||
authProvider: 'local',
|
||||
email: 'mock@hedgedoc.test'
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
33
src/pages/api/mock-backend/private/me/media.ts
Normal file
33
src/pages/api/mock-backend/private/me/media.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { MediaUpload } from '../../../../../api/media/types'
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
respondToMatchingRequest<MediaUpload[]>(HttpMethod.GET, req, res, [
|
||||
{
|
||||
username: 'tilman',
|
||||
createdAt: '2022-03-20T20:36:32Z',
|
||||
url: 'https://dummyimage.com/256/f00',
|
||||
noteId: 'features'
|
||||
},
|
||||
{
|
||||
username: 'tilman',
|
||||
createdAt: '2022-03-20T20:36:57+0000',
|
||||
url: 'https://dummyimage.com/256/00f',
|
||||
noteId: null
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
export default handler
|
33
src/pages/api/mock-backend/private/media.ts
Normal file
33
src/pages/api/mock-backend/private/media.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import type { MediaUpload } from '../../../../api/media/types'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../handler-utils/respond-to-matching-request'
|
||||
import { isMockMode, isTestMode } from '../../../../utils/test-modes'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
|
||||
if (isMockMode && !isTestMode) {
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 3000)
|
||||
})
|
||||
}
|
||||
|
||||
respondToMatchingRequest<MediaUpload>(
|
||||
HttpMethod.POST,
|
||||
req,
|
||||
res,
|
||||
{
|
||||
url: '/mock-public/img/avatar.png',
|
||||
noteId: null,
|
||||
username: 'test',
|
||||
createdAt: '2022-02-27T21:54:23.856Z'
|
||||
},
|
||||
201
|
||||
)
|
||||
}
|
||||
|
||||
export default handler
|
54
src/pages/api/mock-backend/private/notes/features/index.ts
Normal file
54
src/pages/api/mock-backend/private/notes/features/index.ts
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { RevisionDetails } from '../../../../../../../api/revisions/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse): void => {
|
||||
respondToMatchingRequest<RevisionDetails>(HttpMethod.GET, req, res, {
|
||||
id: 0,
|
||||
createdAt: '2021-12-21T16:59:42.000Z',
|
||||
patch: '',
|
||||
edits: [],
|
||||
length: 2782,
|
||||
authorUsernames: [],
|
||||
anonymousAuthorCount: 2,
|
||||
content:
|
||||
'---\ntitle: Features\ndescription: Many features, such wow!\nrobots: noindex\ntags: hedgedoc, demo, react\nopengraph:\n title: Features\n---\n# Embedding demo\n[TOC]\n\n## some plain text\n\nLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n\n## MathJax\nYou can render *LaTeX* mathematical expressions using **MathJax**, as on [math.stackexchange.com](https://math.stackexchange.com/):\n\nThe *Gamma function* satisfying $\\Gamma(n) = (n-1)!\\quad\\forall n\\in\\mathbb N$ is via the Euler integral\n\n$$\nx = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.\n$$\n\n$$\n\\Gamma(z) = \\int_0^\\infty t^{z-1}e^{-t}dt\\,.\n$$\n\n> More information about **LaTeX** mathematical expressions [here](https://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference).\n\n## Blockquote\n> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.\n> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.\n> [color=red] [name=John Doe] [time=2020-06-21 22:50]\n\n## Slideshare\n{%slideshare mazlan1/internet-of-things-the-tip-of-an-iceberg %}\n\n## Gist\nhttps://gist.github.com/schacon/1\n\n## YouTube\nhttps://www.youtube.com/watch?v=KgMpKsp23yY\n\n## Vimeo\nhttps://vimeo.com/23237102\n\n## Asciinema\nhttps://asciinema.org/a/117928\n\n## PDF\n{%pdf https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf %}\n\n## Code highlighting\n```javascript=\n\nlet a = 1\n```\n\n## PlantUML\n```plantuml\n@startuml\nparticipant Alice\nparticipant "The **Famous** Bob" as Bob\n\nAlice -> Bob : hello --there--\n... Some ~~long delay~~ ...\nBob -> Alice : ok\nnote left\n This is **bold**\n This is //italics//\n This is ""monospaced""\n This is --stroked--\n This is __underlined__\n This is ~~waved~~\nend note\n\nAlice -> Bob : A //well formatted// message\nnote right of Alice\n This is <back:cadetblue><size:18>displayed</size></back>\n __left of__ Alice.\nend note\nnote left of Bob\n <u:red>This</u> is <color #118888>displayed</color>\n **<color purple>left of</color> <s:red>Alice</strike> Bob**.\nend note\nnote over Alice, Bob\n <w:#FF33FF>This is hosted</w> by <img sourceforge.jpg>\nend note\n@enduml\n```\n\n'
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { RevisionDetails } from '../../../../../../../api/revisions/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse): void => {
|
||||
respondToMatchingRequest<RevisionDetails>(HttpMethod.GET, req, res, {
|
||||
id: 1,
|
||||
createdAt: '2021-12-29T17:54:11.000Z',
|
||||
patch: '',
|
||||
edits: [],
|
||||
length: 2788,
|
||||
authorUsernames: [],
|
||||
anonymousAuthorCount: 4,
|
||||
content:
|
||||
'---\ntitle: Features\ndescription: Many more features, such wow!\nrobots: noindex\ntags: hedgedoc, demo, react\nopengraph:\n title: Features\n---\n# Embedding demo\n[TOC]\n\n## some plain text\n\nLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magnus aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetezur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam _et_ justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n\n## MathJax\nYou can render *LaTeX* mathematical expressions using **MathJax**, as on [math.stackexchange.com](https://math.stackexchange.com/):\n\nThe *Gamma function* satisfying $\\Gamma(n) = (n-1)!\\quad\\forall n\\in\\mathbb N$ is via the Euler integral\n\n$$\nx = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.\n$$\n\n$$\n\\Gamma(z) = \\int_0^\\infty t^{z-1}e^{-t}dt\\,.\n$$\n\n> More information about **LaTeX** mathematical expressions [here](https://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference).\n\n## Blockquote\n> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.\n> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.\n> [color=red] [name=John Doe] [time=2020-06-21 22:50]\n\n## Slideshare\n{%slideshare mazlan1/internet-of-things-the-tip-of-an-iceberg %}\n\n## Gist\nhttps://gist.github.com/schacon/1\n\n## YouTube\nhttps://www.youtube.com/watch?v=zHAIuE5BQWk\n\n## Vimeo\nhttps://vimeo.com/23237102\n\n## Asciinema\nhttps://asciinema.org/a/117928\n\n## PDF\n{%pdf https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf %}\n\n## Code highlighting\n```javascript=\n\nlet a = 1\n```\n\n## PlantUML\n```plantuml\n@startuml\nparticipant Alice\nparticipant "The **Famous** Bob" as Bob\n\nAlice -> Bob : bye --there--\n... Some ~~long delay~~ ...\nBob -> Alice : ok\nnote left\n This is **bold**\n This is //italics//\n This is ""monospaced""\n This is --stroked--\n This is __underlined__\n This is ~~waved~~\nend note\n\nAlice -> Bob : A //well formatted// message\nnote right of Alice\n This is <back:cadetblue><size:18>displayed</size></back>\n __left of__ Alice.\nend note\nnote left of Bob\n <u:red>This</u> is <color #118888>displayed</color>\n **<color purple>left of</color> <s:red>Alice</strike> Bob**.\nend note\nnote over Alice, Bob\n <w:#FF33FF>This is hosted</w> by <img sourceforge.jpg>\nend note\n@enduml\n```\n\n'
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { RevisionMetadata } from '../../../../../../../api/revisions/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse): void => {
|
||||
respondToMatchingRequest<RevisionMetadata[]>(HttpMethod.GET, req, res, [
|
||||
{
|
||||
id: 1,
|
||||
createdAt: '2021-12-29T17:54:11.000Z',
|
||||
length: 2788,
|
||||
authorUsernames: [],
|
||||
anonymousAuthorCount: 4
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
createdAt: '2021-12-21T16:59:42.000Z',
|
||||
length: 2782,
|
||||
authorUsernames: [],
|
||||
anonymousAuthorCount: 2
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
export default handler
|
File diff suppressed because one or more lines are too long
29
src/pages/api/mock-backend/private/tokens.ts
Normal file
29
src/pages/api/mock-backend/private/tokens.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import type { AccessToken } from '../../../../api/tokens/types'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../handler-utils/respond-to-matching-request'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
respondToMatchingRequest<AccessToken[]>(HttpMethod.GET, req, res, [
|
||||
{
|
||||
label: 'Demo-App',
|
||||
keyId: 'demo',
|
||||
createdAt: '2021-11-20T23:54:13+01:00',
|
||||
lastUsedAt: '2021-11-20T23:54:13+01:00',
|
||||
validUntil: '2022-11-20'
|
||||
},
|
||||
{
|
||||
label: 'CLI @ Test-PC',
|
||||
keyId: 'cli',
|
||||
createdAt: '2021-11-20T23:54:13+01:00',
|
||||
lastUsedAt: '2021-11-20T23:54:13+01:00',
|
||||
validUntil: '2021-11-20'
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
export default handler
|
18
src/pages/api/mock-backend/private/users/erik.ts
Normal file
18
src/pages/api/mock-backend/private/users/erik.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { UserInfo } from '../../../../../api/users/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse): void => {
|
||||
respondToMatchingRequest<UserInfo>(HttpMethod.GET, req, res, {
|
||||
username: 'erik',
|
||||
displayName: 'Erik',
|
||||
photo: '/mock-public/img/avatar.png'
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
19
src/pages/api/mock-backend/private/users/molly.ts
Normal file
19
src/pages/api/mock-backend/private/users/molly.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { UserInfo } from '../../../../../api/users/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse): void => {
|
||||
respondToMatchingRequest<UserInfo>(HttpMethod.GET, req, res, {
|
||||
username: 'molly',
|
||||
displayName: 'Molly',
|
||||
photo: '/mock-public/img/avatar.png'
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
18
src/pages/api/mock-backend/private/users/tilman.ts
Normal file
18
src/pages/api/mock-backend/private/users/tilman.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { HttpMethod, respondToMatchingRequest } from '../../../../../handler-utils/respond-to-matching-request'
|
||||
import type { UserInfo } from '../../../../../api/users/types'
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse): void => {
|
||||
respondToMatchingRequest<UserInfo>(HttpMethod.GET, req, res, {
|
||||
username: 'tilman',
|
||||
displayName: 'Tilman',
|
||||
photo: '/mock-public/img/avatar.png'
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
|
@ -4,16 +4,19 @@
|
|||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import React, { useMemo } from 'react'
|
||||
import { Card, Col, Row } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { ShowIf } from '../components/common/show-if/show-if'
|
||||
import { ViaLocal } from '../components/login-page/auth/via-local'
|
||||
import { ViaLdap } from '../components/login-page/auth/via-ldap'
|
||||
import { OneClickType, ViaOneClick } from '../components/login-page/auth/via-one-click'
|
||||
import { ViaOneClick } from '../components/login-page/auth/via-one-click'
|
||||
import { useApplicationState } from '../hooks/common/use-application-state'
|
||||
import { LandingLayout } from '../components/landing-layout/landing-layout'
|
||||
import { RedirectBack } from '../components/common/redirect-back'
|
||||
import type { AuthProviderWithCustomName } from '../api/config/types'
|
||||
import { AuthProviderType } from '../api/config/types'
|
||||
import { filterOneClickProviders } from '../components/login-page/auth/utils'
|
||||
|
||||
/**
|
||||
* Renders the login page with buttons and fields for the enabled auth providers.
|
||||
|
@ -22,44 +25,34 @@ import { RedirectBack } from '../components/common/redirect-back'
|
|||
export const LoginPage: React.FC = () => {
|
||||
useTranslation()
|
||||
const authProviders = useApplicationState((state) => state.config.authProviders)
|
||||
const customSamlAuthName = useApplicationState((state) => state.config.customAuthNames.saml)
|
||||
const customOauthAuthName = useApplicationState((state) => state.config.customAuthNames.oauth2)
|
||||
const userLoggedIn = useApplicationState((state) => !!state.user)
|
||||
|
||||
const oneClickProviders = [
|
||||
authProviders.dropbox,
|
||||
authProviders.facebook,
|
||||
authProviders.github,
|
||||
authProviders.gitlab,
|
||||
authProviders.google,
|
||||
authProviders.oauth2,
|
||||
authProviders.saml,
|
||||
authProviders.twitter
|
||||
]
|
||||
const ldapProviders = useMemo(() => {
|
||||
return authProviders
|
||||
.filter((provider) => provider.type === AuthProviderType.LDAP)
|
||||
.map((provider) => {
|
||||
const ldapProvider = provider as AuthProviderWithCustomName
|
||||
return (
|
||||
<ViaLdap
|
||||
providerName={ldapProvider.providerName}
|
||||
identifier={ldapProvider.identifier}
|
||||
key={ldapProvider.identifier}
|
||||
/>
|
||||
)
|
||||
})
|
||||
}, [authProviders])
|
||||
|
||||
const oneClickCustomName = useCallback(
|
||||
(type: OneClickType): string | undefined => {
|
||||
switch (type) {
|
||||
case OneClickType.SAML:
|
||||
return customSamlAuthName
|
||||
case OneClickType.OAUTH2:
|
||||
return customOauthAuthName
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
[customOauthAuthName, customSamlAuthName]
|
||||
)
|
||||
const localLoginEnabled = useMemo(() => {
|
||||
return authProviders.some((provider) => provider.type === AuthProviderType.LOCAL)
|
||||
}, [authProviders])
|
||||
|
||||
const oneClickButtonsDom = useMemo(() => {
|
||||
return Object.values(OneClickType)
|
||||
.filter((value) => authProviders[value])
|
||||
.map((value) => (
|
||||
<div className='p-2 d-flex flex-column social-button-container' key={value}>
|
||||
<ViaOneClick oneClickType={value} optionalName={oneClickCustomName(value)} />
|
||||
</div>
|
||||
))
|
||||
}, [authProviders, oneClickCustomName])
|
||||
const oneClickProviders = useMemo(() => {
|
||||
return authProviders.filter(filterOneClickProviders).map((provider, index) => (
|
||||
<div className={'p-2 d-flex flex-column social-button-container'} key={index}>
|
||||
<ViaOneClick provider={provider} />
|
||||
</div>
|
||||
))
|
||||
}, [authProviders])
|
||||
|
||||
if (userLoggedIn) {
|
||||
return <RedirectBack />
|
||||
|
@ -69,24 +62,22 @@ export const LoginPage: React.FC = () => {
|
|||
<LandingLayout>
|
||||
<div className='my-3'>
|
||||
<Row className='h-100 flex justify-content-center'>
|
||||
<ShowIf condition={authProviders.local || authProviders.ldap}>
|
||||
<ShowIf condition={ldapProviders.length > 0 || localLoginEnabled}>
|
||||
<Col xs={12} sm={10} lg={4}>
|
||||
<ShowIf condition={authProviders.local}>
|
||||
<ShowIf condition={localLoginEnabled}>
|
||||
<ViaLocal />
|
||||
</ShowIf>
|
||||
<ShowIf condition={authProviders.ldap}>
|
||||
<ViaLdap />
|
||||
</ShowIf>
|
||||
{ldapProviders}
|
||||
</Col>
|
||||
</ShowIf>
|
||||
<ShowIf condition={oneClickProviders.includes(true)}>
|
||||
<ShowIf condition={oneClickProviders.length > 0}>
|
||||
<Col xs={12} sm={10} lg={4}>
|
||||
<Card className='bg-dark mb-4'>
|
||||
<Card.Body>
|
||||
<Card.Title>
|
||||
<Trans i18nKey='login.signInVia' values={{ service: '' }} />
|
||||
</Card.Title>
|
||||
{oneClickButtonsDom}
|
||||
{oneClickProviders}
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</Col>
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import React from 'react'
|
||||
import { Col, Row } from 'react-bootstrap'
|
||||
import { useApplicationState } from '../hooks/common/use-application-state'
|
||||
import { LoginProvider } from '../redux/user/types'
|
||||
import { ShowIf } from '../components/common/show-if/show-if'
|
||||
import { ProfileAccessTokens } from '../components/profile-page/access-tokens/profile-access-tokens'
|
||||
import { ProfileAccountManagement } from '../components/profile-page/account-management/profile-account-management'
|
||||
|
@ -15,13 +14,14 @@ import { ProfileChangePassword } from '../components/profile-page/settings/profi
|
|||
import { ProfileDisplayName } from '../components/profile-page/settings/profile-display-name'
|
||||
import { LandingLayout } from '../components/landing-layout/landing-layout'
|
||||
import { Redirect } from '../components/common/redirect'
|
||||
import { AuthProviderType } from '../api/config/types'
|
||||
|
||||
/**
|
||||
* Profile page that includes forms for changing display name, password (if internal login is used),
|
||||
* managing access tokens and deleting the account.
|
||||
*/
|
||||
export const ProfilePage: React.FC = () => {
|
||||
const userProvider = useApplicationState((state) => state.user?.provider)
|
||||
const userProvider = useApplicationState((state) => state.user?.authProvider)
|
||||
|
||||
if (!userProvider) {
|
||||
return <Redirect to={'/login'} />
|
||||
|
@ -33,7 +33,7 @@ export const ProfilePage: React.FC = () => {
|
|||
<Row className='h-100 flex justify-content-center'>
|
||||
<Col lg={6}>
|
||||
<ProfileDisplayName />
|
||||
<ShowIf condition={userProvider === LoginProvider.LOCAL}>
|
||||
<ShowIf condition={userProvider === AuthProviderType.LOCAL}>
|
||||
<ProfileChangePassword />
|
||||
</ShowIf>
|
||||
<ProfileAccessTokens />
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
import { doLocalRegister } from '../api/auth/local'
|
||||
import { useApplicationState } from '../hooks/common/use-application-state'
|
||||
import { fetchAndSetUser } from '../components/login-page/auth/utils'
|
||||
import { RegisterError as RegisterErrorType } from '../api/auth'
|
||||
import { RegisterError as RegisterErrorType } from '../api/auth/types'
|
||||
import { RegisterInfos } from '../components/register-page/register-infos/register-infos'
|
||||
import { UsernameField } from '../components/common/fields/username-field'
|
||||
import { DisplayNameField } from '../components/common/fields/display-name-field'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue