diff --git a/config-spec.xml b/config-spec.xml
new file mode 100644
index 0000000..b2f573f
--- /dev/null
+++ b/config-spec.xml
@@ -0,0 +1,79 @@
+
+
+
+ configuration-bundle
+ React Native HAAPI Demo Client
+ Configure a client for the HAAPI demo
+
+
+
+ TOKEN_PROFILE
+ /profiles/profile/id
+ The profile where to add the client
+ profile
+
+
+ HAAPI_CLIENT
+
+ The ID of the client to add
+ string
+
+
+
+
+
+
+
+ #{TOKEN_PROFILE}
+ as:oauth-service
+
+
+
+
+
+ #{HAAPI_CLIENT}
+ true
+ http://localhost:3000/
+
+ true
+
+ disabled
+ openid
+ profile
+
+
+ http://localhost:3000
+
+
+
+
+ false
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /profiles/profile{#{TOKEN_PROFILE} oauth-service}/id
+ The provided profile does not exist or is not a token profile.
+
+
+
+ /profiles/profile{#{TOKEN_PROFILE} oauth-service}/settings/authorization-server/client-store/config-backed/client{#{HAAPI_CLIENT}}
+
+ A client with ID ${HAAPI_CLIENT} already exist. Please select a new ID.
+
+
+
\ No newline at end of file
diff --git a/src/components/HAAPIProcessor.js b/src/components/HAAPIProcessor.js
index 2215467..501132e 100644
--- a/src/components/HAAPIProcessor.js
+++ b/src/components/HAAPIProcessor.js
@@ -19,6 +19,7 @@ import StartAuthorization from "./StartAuthorization";
/* UI Authenticators */
import UsernamePassword from "../ui-kit/authenticators/UsernamePassword";
+import FormBased from "../ui-kit/authenticators/FormBased";
/* UI Containers */
import Selector from "../ui-kit/containers/Selector";
@@ -80,10 +81,17 @@ export default function HAAPIProcessor(props) {
/>
case 'authenticator/external-browser/launch':
setStep({ name: 'external-browser-launch', haapiResponse: step.haapiResponse })
- return
+ return
default:
- setStep({ name: 'unknown-step', haapiResponse: step.haapiResponse })
- setMissingResponseType('Authentication Step')
+ return submitForm(formState, url, method)}
+ isLoading={isLoading}
+ clickLink={(url) => clickLink(url)}
+ inputProblem={step.inputProblem}
+ />
+ //setStep({ name: 'unknown-step', haapiResponse: step.haapiResponse })
+ //setMissingResponseType('Authentication Step')
}
}
@@ -121,6 +129,7 @@ export default function HAAPIProcessor(props) {
case 'registration-step':
setStep({ name: 'registration-step', haapiResponse })
break
+ case 'https://curity.se/problems/generic-user-error':
case 'https://curity.se/problems/incorrect-credentials':
setStep({ name: step.haapiResponse.type, haapiResponse: step.haapiResponse, problem: haapiResponse })
break
@@ -366,4 +375,4 @@ const getRedirectBody = (fields) => {
}
return new URLSearchParams(fields.map(field => [field.name, field.value]))
-}
+}
\ No newline at end of file
diff --git a/src/config.js b/src/config.js
index f2fd7b7..c7a74d0 100644
--- a/src/config.js
+++ b/src/config.js
@@ -22,4 +22,4 @@ const config = {
tokenEndpoint: 'https://localhost:8443/oauth/v2/oauth-token'
}
-export default config
+export default config
\ No newline at end of file
diff --git a/src/scss/curity-example-app.scss b/src/scss/curity-example-app.scss
index 853dfde..c9a5abd 100644
--- a/src/scss/curity-example-app.scss
+++ b/src/scss/curity-example-app.scss
@@ -37,7 +37,7 @@
}
-.example-app-settings pre {
+.example-app-settings pre , .example-app-wrapper pre {
background-color: #15161d;
border: none;
color: #f8f8f2;
@@ -48,22 +48,27 @@
line-height: 1.5;
}
+.example-app-wrapper pre .json-mark,
.example-app-settings pre .json-mark {
color: white;
}
+.example-app-wrapper pre .json-key,
.example-app-settings pre .json-key {
color: #ff79c6;
}
+.example-app-wrapper pre .json-number,
.example-app-settings pre .json-number {
color: #e7ca45;
}
+.example-app-wrapper pre .json-link,
.example-app-settings pre .json-link {
color: white;
}
+.example-app-wrapper pre .json-string,
.example-app-settings pre .json-string {
color: #50fa7b;
}
diff --git a/src/ui-kit/authenticators/FormBased.js b/src/ui-kit/authenticators/FormBased.js
new file mode 100644
index 0000000..5d377a0
--- /dev/null
+++ b/src/ui-kit/authenticators/FormBased.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2024 Curity AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React, {useState} from "react";
+
+/* UI Containers */
+import Form from "../containers/Form";
+import Message from "../ui-components/Message";
+
+/* UI Components */
+import { Layout, Page, Well, Logo } from "../ui-components";
+
+export default function FormBased(props) {
+ const { actions, links, messages } = props.haapiResponse
+ const { model, title } = actions[0]
+ const otherActions = actions.slice(1)
+
+ const [state, setState] = useState(new URLSearchParams())
+
+ const onChange = (name, value) => {
+ setState((prevState) => {
+ prevState.set(name, value)
+ return prevState
+ })
+ }
+
+ const computedTitle =
+ // (messages && messages.find(m => m.classList.includes("heading"))?.text)
+ // || title
+ title
+ || model.title
+
+ const messageList = [];
+ if(messages) {
+ messages.forEach((msg, index) => {
+ messageList.push();
+ });
+ }
+
+
+ return (
+
+
+
+
+ { messageList }
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/ui-kit/ui-components/Message/index.js b/src/ui-kit/ui-components/Message/index.js
new file mode 100644
index 0000000..05d0d34
--- /dev/null
+++ b/src/ui-kit/ui-components/Message/index.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2024 Curity AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react";
+
+import { prettyPrintJson } from "pretty-print-json";
+
+const Message = (props) => {
+ const { message } = props;
+
+ let messageComponent;
+ if(message.classList.includes('json')) {
+ messageComponent = (
+
+ );
+ }
+ else if (message.classList.includes('heading')) {
+ messageComponent = ({message.text}
);
+ } else {
+ messageComponent = (
+
+ );
+ }
+
+ return messageComponent;
+};
+
+export default Message;
\ No newline at end of file