Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oidc-client #37

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
REACT_APP_BACKEND_URL = 'http://127.0.0.1:5000/api'
REACT_APP_OIDC_CLIENT_REDIRECT_URL = "http://localhost:3000"
3 changes: 2 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
REACT_APP_BACKEND_URL = 'https://oktatools.tecnics.com/api'
REACT_APP_BACKEND_URL = 'https://oktatools.tecnics.com/api'
REACT_APP_OIDC_CLIENT_REDIRECT_URL = "https://oktatools.tecnics.com"
10 changes: 6 additions & 4 deletions api/jwt_decoder.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import jwt


class jwt_viewer:
def decode_encoded_string(encoded_string):
error = None
header = None
decoded = None
try:
header = jwt.get_unverified_header(encoded_string)
print(header);
decoded = jwt.decode(encoded_string, options={"verify_signature": False})
print(header)
decoded = jwt.decode(encoded_string, options={
"verify_signature": False})
except Exception as e:
error = "Please Enter a valid token!"
error = "Please enter a valid token!"
data = {
"header": header,
"payload": decoded,
"error": error
}
return data

1,650 changes: 770 additions & 880 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 14 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@hookform/resolvers": "^2.8.2",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^27.0.2",
"@types/node": "^16.11.6",
"@types/react": "^17.0.33",
"@types/react-dom": "^17.0.10",
"axios": "^0.21.1",
"cdbreact": "^1.1.0",
"dotenv": "^10.0.0",
"env-cmd": "^10.1.0",
"http-proxy-middleware": "^2.0.1",
"js-base64": "^3.7.2",
"js-file-download": "^0.4.12",
Expand All @@ -19,21 +25,25 @@
"react-bootstrap": "^1.6.1",
"react-dom": "^17.0.2",
"react-download-link": "^2.3.0",
"react-hook-form": "^7.18.0",
"react-icons": "^4.2.0",
"react-json-view": "^1.21.3",
"react-json-viewer": "^2.1.0",
"react-loader-spinner": "^4.0.0",
"react-pure-lifecycle": "^3.0.0",
"react-router-dom": "^5.2.0",
"react-router-dom": "^5.3.0",
"react-scripts": "^4.0.3",
"react-xml-viewer": "^1.3.0",
"rsuite": "^4.10.2",
"typescript": "^4.4.4",
"use-debounce": "^7.0.0",
"web-vitals": "^1.0.1",
"xml-formatter": "^2.4.0"
"xml-formatter": "^2.4.0",
"yup": "^0.32.11"
},
"scripts": {
"start": "react-scripts start",
"start:staging": "env-cmd -f .env react-scripts start",
"start:prod": "env-cmd -f .env.production react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
Expand All @@ -56,4 +66,4 @@
"last 1 safari version"
]
}
}
}
42 changes: 42 additions & 0 deletions src/components/CustomInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useState, useEffect } from "react";

interface iCustomInput {
labelText: string;
placeholder: string;
id: string;
name: string;
register: (arg0: any, arg1: any) => any;
errors?: any;
required?: boolean;
errorMessage?: string;
format?: any;
pattern?: string;
}
const CustomInput: React.FC<iCustomInput> = (props) => {
const {
labelText, placeholder, id, name, errors, required, errorMessage, register, format
} = props;

const errorComponent = (data: string) => {
return (<div className="form-text error-msg">Please enter {data}</div>);
}

const divClassName = () => {
if (props.required) {
return ("mb-3 col-6 form-group required");
}
else {
return ("mb-3 col-6 form-group");
}
}

return (
<div className={divClassName()}>
<label className="form-label">{labelText}</label>
<input className="form-control" placeholder={placeholder} {...register(name, { required: required, pattern: format ? format : '' })} id={id} name={name} />
{errors && errorComponent(errorMessage ? errorMessage : "this field")}
</div>
)
}

export default CustomInput;
218 changes: 218 additions & 0 deletions src/components/OidcClient.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import React, { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
// import { yupResolver } from '@hookform/resolvers/yup';
// import * as Yup from 'yup';
import CustomInput from "./CustomInput";
// import * as ReactDOM from 'react-dom';
import * as dotenv from 'dotenv';
// dotenv.config({ path: 'okta-tools/src/.env' });

const OidcClient = () => {

type FormValues = {
authorizeUri: string;
redirectUri: string;
clientId: string;
scope: string;
state: string;
nonce: string;
uriValidationError: string;
// responseType: string;
// responseMode: string;
};

const redirectUrl = process.env.REACT_APP_OIDC_CLIENT_REDIRECT_URL ?? "";

const preloadedValues = {
redirectUri: redirectUrl
};
const { register, handleSubmit, formState: { errors } } = useForm<FormValues>({ mode: "onBlur", reValidateMode: "onChange", defaultValues: preloadedValues });

const [selectedCheckbox, setSelectedCheckbox] = useState('');
const [selectedRadioButton, setSelectedRadioButton] = useState('');
const [checkboxErrorMessage, setCheckboxErrorMessage] = useState(false);
const [radioButtonErrorMessage, setRadioButtonErrorMessage] = useState(false);
const [showUriValidationErrorMessage, setShowUriValidationErrorMessage] = useState(false);
function errorComponent(data: string) {
return (<div className="form-text error-msg">Please enter {data}</div>);
}

const handleCheckbox = (event: any) => {
if (selectedCheckbox.length > 0) {
setSelectedCheckbox(selectedCheckbox + ' ' + event.target.value);
}
else {
setSelectedCheckbox(event.target.value);
}
};

const handleRadioButton = (event: any) => {
setSelectedRadioButton(event.target.value);
}

const isDataValid = () => {
let flag = false;
if (selectedCheckbox === '') {
setCheckboxErrorMessage(true);
flag = true;
}
if (selectedRadioButton === '') {
setRadioButtonErrorMessage(true);
flag = true;
}
if (flag) {
return false;
}
return true;
}

const resetErrorMessages = () => {
setCheckboxErrorMessage(false);
setRadioButtonErrorMessage(false);
setShowUriValidationErrorMessage(false);
}

const regex = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi;

const validateUri = (data: string) => {
if (data.match(regex)) {
return true;
}
else {
setShowUriValidationErrorMessage(true);
return false;
}
}

const onSubmit = (data: any) => {
resetErrorMessages();
if (!isDataValid()) {
return;
}
var authorizeUriValidation = validateUri(data.authorizeUri);
if (authorizeUriValidation) {
const url = `${data.authorizeUri}?client_id=${data.clientId}&redirect_uri=${data.redirectUri}&scope=${data.scope}
&response_type=${selectedCheckbox}&response_mode=${selectedRadioButton}&state=${data.state}&nonce=${data.nonce}`;
window.location.assign(url);
}
else {
// console.log("Hello");
// console.log(showUriValidationErrorMessage);
}
}

return (
<div id="oidc-client" className="container-fluid">
<form onSubmit={handleSubmit(onSubmit)}>
<CustomInput
labelText={"Authorize URI"}
placeholder={"Enter Authorize URI"}
id={"authorizeUri"}
name={"authorizeUri"}
register={register}
errors={errors.authorizeUri}
required={true}
errorMessage={"valid Authorize URI"}
format={regex}
></CustomInput>
<CustomInput
labelText={"Redirect URI"}
placeholder={"Enter Redirect URI"}
id={"redirectUri"}
name={"redirectUri"}
register={register}
errors={errors.redirectUri}
required={true}
errorMessage={"valid Redirect URI"}
// format={regex}
></CustomInput>
<CustomInput
labelText={"Client ID"}
placeholder={"Enter Client ID"}
id={"clientId"}
name={"clientId"}
register={register}
errors={errors.clientId}
required={true}
errorMessage="Client ID"
></CustomInput>
<CustomInput
labelText={"Scope"}
placeholder={"Enter Scope"}
id={"scope"}
name={"scope"}
register={register}
errors={errors.scope}
required={true}
errorMessage="Scope"
></CustomInput>
<CustomInput
labelText={"State"}
placeholder={"Enter State"}
id={"state"}
name={"state"}
register={register}
errors={errors.state}
required={false}
errorMessage="State"
></CustomInput>
<CustomInput
labelText={"Nonce"}
placeholder={"Enter Nonce"}
id={"nonce"}
name={"nonce"}
register={register}
errors={errors.nonce}
required={false}
errorMessage="Nonce"
></CustomInput>
<div className="mb-3 col-6 form-group required" id="responseType">
<label htmlFor="responseType" className="form-label">
Response Type
</label><br></br>
<div className="form-check form-check-inline">
<input onChange={handleCheckbox} className="form-check-input" type="checkbox" id="responseType-code" value="code" />
<label className="form-check-label" htmlFor="responseType-code" id="code">code &nbsp;</label>
</div>
<div className="form-check form-check-inline">
<input onChange={handleCheckbox} className="form-check-input" type="checkbox" id="responseType-token" value="token" />
<label className="form-check-label" htmlFor="responseType-token" id="token">token &nbsp;</label>
</div>
<div className="form-check form-check-inline">
<input onChange={handleCheckbox} className="form-check-input" type="checkbox" id="responseType-idToken" value="id_token" />
<label className="form-check-label" htmlFor="responseType-idToken" id="idToken">id_token</label>
</div>
{checkboxErrorMessage && errorComponent("Response Type")}
</div>
<div className="mb-3 col-6 form-group required" id="responseMode">
<label htmlFor="responseMode" className="form-label">
Response Mode
</label><br></br>
<div className="form-check form-check-inline">
<input onChange={handleRadioButton} className="form-check-input" type="radio" name="responseMode" id="responseMode-query" value="query" />
<label className="form-check-label" htmlFor="responseMode-query" id="query">query &nbsp;</label>
</div>
<div className="form-check form-check-inline">
<input onChange={handleRadioButton} className="form-check-input" type="radio" name="responseMode" id="responseMode-formPost" value="form_post" />
<label className="form-check-label" htmlFor="responseMode-formPost" id="formPost">form_post &nbsp;</label>
</div>
<div className="form-check form-check-inline">
<input onChange={handleRadioButton} className="form-check-input" type="radio" name="responseMode" id="responseMode-fragment" value="fragment" />
<label className="form-check-label" htmlFor="responseMode-fragment" id="fragment">fragment</label>
</div>
{radioButtonErrorMessage && errorComponent("Response Mode")}
</div>
<div className="mb-3 col-6 form-group">
<button
className="btn btn-primary"
>
Send Request
</button>
</div>
</form>
</div >
)
}

export default OidcClient;

Loading