Skip to content

Commit

Permalink
Merge branch 'master' into libs-598-replace-cra-with-vite
Browse files Browse the repository at this point in the history
  • Loading branch information
KaiVandivier committed May 8, 2024
2 parents 6e34184 + f7a7e24 commit 293933b
Show file tree
Hide file tree
Showing 18 changed files with 230 additions and 85 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,17 @@
## [11.2.2](https://github.com/dhis2/app-platform/compare/v11.2.1...v11.2.2) (2024-05-06)


### Bug Fixes

* allow apps to opt out of plugin logic [LIBS-579] ([#833](https://github.com/dhis2/app-platform/issues/833)) ([d450758](https://github.com/dhis2/app-platform/commit/d450758ef2e7cde7bf45a19e97f0e262a0e5f3d8))

## [11.2.1](https://github.com/dhis2/app-platform/compare/v11.2.0...v11.2.1) (2024-04-29)


### Bug Fixes

* handle new login endpoints [LIBS-600] ([#846](https://github.com/dhis2/app-platform/issues/846)) ([4512825](https://github.com/dhis2/app-platform/commit/4512825bab1a58be78ed7183763c4e0568489fab))

# [11.2.0](https://github.com/dhis2/app-platform/compare/v11.1.1...v11.2.0) (2024-04-25)


Expand Down
28 changes: 23 additions & 5 deletions adapter/i18n/en.pot
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-03-14T15:31:40.141Z\n"
"PO-Revision-Date: 2024-03-14T15:31:40.141Z\n"
"POT-Creation-Date: 2024-04-24T13:58:13.591Z\n"
"PO-Revision-Date: 2024-04-24T13:58:13.591Z\n"

msgid "Save your data"
msgstr "Save your data"
Expand Down Expand Up @@ -48,6 +48,9 @@ msgstr "Something went wrong"
msgid "Redirect to safe login mode"
msgstr "Redirect to safe login mode"

msgid "Redirect to safe login mode"
msgstr "Redirect to safe login mode"

msgid "Hide technical details"
msgstr "Hide technical details"

Expand All @@ -60,9 +63,27 @@ msgstr "The following information may be requested by technical support."
msgid "Copy technical details to clipboard"
msgstr "Copy technical details to clipboard"

msgid "Signing in..."
msgstr "Signing in..."

msgid "Sign in"
msgstr "Sign in"

msgid "Going to app..."
msgstr "Going to app..."

msgid "Go to app"
msgstr "Go to app"

msgid "Please sign in"
msgstr "Please sign in"

msgid "Specify server"
msgstr "Specify server"

msgid "Could not log in"
msgstr "Could not log in"

msgid "Server"
msgstr "Server"

Expand All @@ -71,6 +92,3 @@ msgstr "Username"

msgid "Password"
msgstr "Password"

msgid "Sign in"
msgstr "Sign in"
6 changes: 3 additions & 3 deletions adapter/package.json
@@ -1,6 +1,6 @@
{
"name": "@dhis2/app-adapter",
"version": "11.2.0",
"version": "11.2.2",
"repository": {
"type": "git",
"url": "https://github.com/amcgee/dhis2-app-platform",
Expand All @@ -21,11 +21,11 @@
"build"
],
"dependencies": {
"@dhis2/pwa": "11.2.0",
"@dhis2/pwa": "11.2.2",
"moment": "^2.24.0"
},
"devDependencies": {
"@dhis2/cli-app-scripts": "11.2.0",
"@dhis2/cli-app-scripts": "11.2.2",
"@testing-library/react": "^12.0.0",
"@testing-library/react-hooks": "^8.0.1",
"enzyme": "^3.11.0",
Expand Down
7 changes: 4 additions & 3 deletions adapter/src/components/LoginAppWrapper.js
@@ -1,3 +1,4 @@
import { useConfig } from '@dhis2/app-runtime'
import PropTypes from 'prop-types'
import React from 'react'
import { useSystemDefaultLocale } from '../utils/useLocale.js'
Expand All @@ -6,8 +7,9 @@ import { ErrorBoundary } from './ErrorBoundary.js'
import { LoadingMask } from './LoadingMask.js'
import { styles } from './styles/AppWrapper.style.js'

export const LoginAppWrapper = ({ url, children }) => {
export const LoginAppWrapper = ({ children }) => {
const { loading: localeLoading } = useSystemDefaultLocale()
const { baseUrl } = useConfig()
// cannot check current user for a loginApp (no api/me)

if (localeLoading) {
Expand All @@ -21,7 +23,7 @@ export const LoginAppWrapper = ({ url, children }) => {
<ErrorBoundary
onRetry={() => window.location.reload()}
loginApp={true}
baseURL={url}
baseURL={baseUrl}
>
{children}
</ErrorBoundary>
Expand All @@ -33,5 +35,4 @@ export const LoginAppWrapper = ({ url, children }) => {

LoginAppWrapper.propTypes = {
children: PropTypes.node,
url: PropTypes.string,
}
160 changes: 122 additions & 38 deletions adapter/src/components/LoginModal.js
Expand Up @@ -6,57 +6,136 @@ import {
ModalActions,
Button,
InputField,
NoticeBox,
} from '@dhis2/ui'
import PropTypes from 'prop-types'
import React, { useState } from 'react'
import i18n from '../locales/index.js'
import { post } from '../utils/api.js'
import { get, post, postJSON } from '../utils/api.js'
import { styles } from './styles/LoginModal.style.js'

// Check if base URL is set statically as an env var (typical in production)
const staticUrl = process.env.REACT_APP_DHIS2_BASE_URL

export const LoginModal = ({ appName, baseUrl }) => {
const getIsNewLoginAPIAvailable = async (server) => {
try {
// if loginConfig is available, the instance can use new endpoints
await get(`${server}/api/loginConfig`)
return true
} catch (e) {
// if loginConfig is not available, the instance must use old endpoints
console.error(e)
return false
}
}

const loginWithNewEndpoints = async ({
server,
username,
password,
setError,
setIsLoggingIn,
}) => {
try {
await postJSON(
`${server}/api/auth/login`,
JSON.stringify({
username: encodeURIComponent(username),
password: encodeURIComponent(password),
})
)
window.location.reload()
} catch (e) {
setError(e)
setIsLoggingIn(false)
}
}

const loginWithOldEndpoints = async ({ server, username, password }) => {
try {
await post(
`${server}/dhis-web-commons-security/login.action`,
`j_username=${encodeURIComponent(
username
)}&j_password=${encodeURIComponent(password)}`
)
} catch (e) {
console.error(e)
} finally {
window.location.reload()
}
}

export const LoginModal = ({ appName, baseUrl, loginApp = false }) => {
const [server, setServer] = useState(baseUrl || '')
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [isDirty, setIsDirty] = useState(false)
const [error, setError] = useState(null)
const [isLoggingIn, setIsLoggingIn] = useState(false)

const isValid = (val) => val && val.length >= 2
const getSignInButtonText = ({ loginApp, isLoggingIn }) => {
if (!loginApp) {
return isLoggingIn ? i18n.t('Signing in...') : i18n.t('Sign in')
}
return isLoggingIn ? i18n.t('Going to app...') : i18n.t('Go to app')
}

const onSubmit = async (e) => {
e.preventDefault()
setIsDirty(true)
if (isValid(server) && isValid(username) && isValid(password)) {
if (
isValid(server) &&
((isValid(username) && isValid(password)) || loginApp)
) {
setIsLoggingIn(true)
if (!staticUrl) {
// keep the localStorage value here -- it's still used in some
// obscure cases, like in the cypress network shim
window.localStorage.DHIS2_BASE_URL = server
await setBaseUrlByAppName({ appName, baseUrl: server })
if (loginApp) {
window.location.reload()
}
}
try {
await post(
`${server}/dhis-web-commons-security/login.action`,
`j_username=${encodeURIComponent(
username
)}&j_password=${encodeURIComponent(password)}`
)
} catch (e) {
console.log(
'TODO: This will always error and cancel the request until we get a real login endpoint!'
)
}

// TODO: Hacky solution... this shouldn't require a reload
window.location.reload()
const isNewLoginAPIAvailable = await getIsNewLoginAPIAvailable(
server
)

if (isNewLoginAPIAvailable) {
loginWithNewEndpoints({
server,
username,
password,
setError,
setIsLoggingIn,
})
} else {
loginWithOldEndpoints({ server, username, password })
}
}
}

return (
<Modal open small dataTest="dhis2-adapter-loginmodal">
<style jsx>{styles}</style>
<form onSubmit={onSubmit}>
<ModalTitle>{i18n.t('Please sign in')}</ModalTitle>
<ModalTitle>
{!loginApp
? i18n.t('Please sign in')
: i18n.t('Specify server')}
</ModalTitle>

<ModalContent>
{error && (
<div className="errorNotification">
<NoticeBox error title={i18n.t('Could not log in')}>
{error?.message}
</NoticeBox>
</div>
)}
{!staticUrl && (
<InputField
dataTest="dhis2-adapter-loginserver"
Expand All @@ -68,35 +147,39 @@ export const LoginModal = ({ appName, baseUrl }) => {
onChange={(input) => setServer(input.value)}
/>
)}
{!loginApp && (
<>
<InputField
dataTest="dhis2-adapter-loginname"
error={isDirty && !isValid(username)}
label={i18n.t('Username')}
name="j_username"
type="text"
value={username}
onChange={(input) => setUsername(input.value)}
/>

<InputField
dataTest="dhis2-adapter-loginname"
error={isDirty && !isValid(username)}
label={i18n.t('Username')}
name="j_username"
type="text"
value={username}
onChange={(input) => setUsername(input.value)}
/>

<InputField
dataTest="dhis2-adapter-loginpassword"
error={isDirty && !isValid(password)}
label={i18n.t('Password')}
name="j_password"
type="password"
value={password}
onChange={(input) => setPassword(input.value)}
/>
<InputField
dataTest="dhis2-adapter-loginpassword"
error={isDirty && !isValid(password)}
label={i18n.t('Password')}
name="j_password"
type="password"
value={password}
onChange={(input) => setPassword(input.value)}
/>
</>
)}
</ModalContent>

<ModalActions>
<Button
primary
dataTest="dhis2-adapter-loginsubmit"
type="submit"
disabled={isLoggingIn}
>
{i18n.t('Sign in')}
{getSignInButtonText({ loginApp, isLoggingIn })}
</Button>
</ModalActions>
</form>
Expand All @@ -106,4 +189,5 @@ export const LoginModal = ({ appName, baseUrl }) => {
LoginModal.propTypes = {
appName: PropTypes.string,
baseUrl: PropTypes.string,
loginApp: PropTypes.bool,
}
10 changes: 6 additions & 4 deletions adapter/src/components/ServerVersionProvider.js
Expand Up @@ -159,10 +159,12 @@ export const ServerVersionProvider = ({

// This needs to come before 'loading' case to show modal at correct times
if (systemInfoState.error || baseUrlState.error) {
return !loginApp ? (
<LoginModal appName={appName} baseUrl={baseUrl} />
) : (
<p>Specify DHIS2_BASE_URL environment variable</p>
return (
<LoginModal
appName={appName}
baseUrl={baseUrl}
loginApp={loginApp}
/>
)
}

Expand Down
7 changes: 7 additions & 0 deletions adapter/src/components/styles/LoginModal.style.js
@@ -0,0 +1,7 @@
import css from 'styled-jsx/css'

export const styles = css`
.errorNotification {
margin-block: 8px;
}
`
2 changes: 1 addition & 1 deletion adapter/src/index.js
Expand Up @@ -43,7 +43,7 @@ const AppAdapter = ({
loginApp={loginApp}
plugin={false}
>
<LoginAppWrapper url={url}>{children}</LoginAppWrapper>
<LoginAppWrapper>{children}</LoginAppWrapper>
</ServerVersionProvider>
</ErrorBoundary>
)
Expand Down

0 comments on commit 293933b

Please sign in to comment.