Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Welcome to OpenSign, the premier open source docusign alternative - document e-s
- **PDF Template Creation:** OpenSign™ allows you to create and store PDF document templates for repeated use thereby saving you a lot of time & collect e-signatures seamlessly.
- **OpenSign™ Drive:** It is a centralised secure vault for your digital documents that makes storing, signing, organizing, sharing & archieving your docs a breeze.
- **Audit Trails & completion certificate:** Being a security focused solution, OpenSign™ makes it a top priority to save detailed logs for tracking document activities along with time-stamps, IP addresses, email IDs & phone numbers. A completion certificate is generated as soon as document is completed which contains all the document related logs for added safety.
- **API Support:** OpenSign™ API allows seamless integration into existing systems and software. You can generate an API key from the app and refer the [official API docs](https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1) to start integrating it in your existing applications.
- **API Support:** OpenSign™ API allows seamless integration into existing systems and software. You can generate an API key from the app and refer the [official API docs](https://docs.opensignlabs.com/docs/API-docs/v1.1) to start integrating it in your existing applications.
- **Integrations:** The open source document signing experience becomes even more seamless because of integrations with various Cloud storage systems, CRMs & enterprise platforms. We also have a Zapier integration that allows you to integrate it with virtually any application.
<img alt="Login page" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/8016edb6-7d6e-4185-ab72-82d2c4a16032" height='200' >
<img alt="Dash_board" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/6e7b96f7-3154-4c25-bc1e-caf33925cc47" height='200'>
Expand Down
1 change: 1 addition & 0 deletions apps/OpenSign/public/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"login-page": "Anmeldeseite",
"or": "ODER",
"signup-page": "Registrierungsseite",
"password-match-length": "Neues Passwort und Bestätigungspasswort sollten übereinstimmen",
"password-length": "Das Passwort sollte 8 Zeichen lang sein",
"password-case": "Das Passwort sollte einen Großbuchstaben, einen Kleinbuchstaben und eine Zahl enthalten",
"password-special-char": "Das Passwort sollte ein Sonderzeichen enthalten",
Expand Down
1 change: 1 addition & 0 deletions apps/OpenSign/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"login-page": "Login P+age",
"or": "OR",
"signup-page": "Signup page",
"password-match-length": "New password and confirmation password should match",
"password-length": "Password should be 8 characters long",
"password-case": "Password should contain uppercase letter, lowercase letter, digit",
"password-special-char": " Password should contain special character",
Expand Down
1 change: 1 addition & 0 deletions apps/OpenSign/public/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"login-page": "Página de inicio de sesión",
"or": "O",
"signup-page": "Página de registro",
"password-match-length": "La nueva contraseña y la confirmación deben coincidir",
"password-length": "La contraseña debe tener 8 caracteres",
"password-case": "La contraseña debe incluir mayúsculas, minúsculas y números",
"password-special-char": " La contraseña debe incluir caracteres especiales",
Expand Down
1 change: 1 addition & 0 deletions apps/OpenSign/public/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"login-page": "Page de connexion",
"or": "OU",
"signup-page": "Page d'inscription",
"password-match-length": "Le nouveau mot de passe et la confirmation doivent correspondre",
"password-length": "Le mot de passe doit être de plus de 8 caractères",
"password-case": "Le mot de passe doit contenir une lettre majuscule, minuscule et un chiffre ",
"password-special-char": "Le mot de passe doit contenir un caractère spécial",
Expand Down
1 change: 1 addition & 0 deletions apps/OpenSign/public/locales/hi/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"login-page": "लॉगिन पृष्ठ",
"or": "या",
"signup-page": "साइनअप पृष्ठ",
"password-match-length": "नया पासवर्ड और पुष्टि पासवर्ड मेल खाना चाहिए",
"password-length": "पासवर्ड 8 वर्ण लंबा होना चाहिए",
"password-case": "पासवर्ड में अपरकेस अक्षर, लोअरकेस अक्षर, अंक होना चाहिए",
"password-special-char": " पासवर्ड में विशेष वर्ण होना चाहिए",
Expand Down
1 change: 1 addition & 0 deletions apps/OpenSign/public/locales/it/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"login-page": "Pagina di accesso",
"or": "O",
"signup-page": "Pagina di registrazione",
"password-match-length": "La nuova password e la conferma devono corrispondere",
"password-length": "La password deve contenere almeno 8 caratteri",
"password-case": "La password deve contenere una lettera maiuscola, una minuscola e un numero",
"password-special-char": "La password deve contenere un carattere speciale",
Expand Down
196 changes: 142 additions & 54 deletions apps/OpenSign/src/pages/ChangePassword.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,70 @@ function ChangePassword() {
const [currentpassword, setCurrentPassword] = useState("");
const [newpassword, setnewpassword] = useState("");
const [confirmpassword, setconfirmpassword] = useState("");
const [lengthValid, setLengthValid] = useState(false);
const [caseDigitValid, setCaseDigitValid] = useState(false);
const [specialCharValid, setSpecialCharValid] = useState(false);
const [showNewPassword, setNewShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const toggleNewPasswordVisibility = () => {
setNewShowPassword(!showNewPassword);
};
const toggleConfirmPasswordVisibility = () => {
setShowConfirmPassword(!showConfirmPassword);
};

const handlePasswordChange = (e) => {
const newPassword = e.target.value;
setconfirmpassword(newPassword);
// Check conditions separately
setLengthValid(newPassword.length >= 8);
setCaseDigitValid(
/[a-z]/.test(newPassword) &&
/[A-Z]/.test(newPassword) &&
/\d/.test(newPassword)
);
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>]/.test(newPassword));
};
const handleSubmit = async (evt) => {
evt.preventDefault();
try {
if (newpassword === confirmpassword) {
Parse.User.logIn(localStorage.getItem("userEmail"), currentpassword)
.then(async (user) => {
if (user) {
const User = new Parse.User();
const query = new Parse.Query(User);
await query.get(user.id).then((user) => {
// Updates the data we want
user.set("password", newpassword);
user
.save()
.then(async () => {
let _user = user.toJSON();
if (_user) {
await Parse.User.become(_user.sessionToken);
localStorage.setItem("accesstoken", _user.sessionToken);
}
alert(t("password-update-alert-1"));
})
.catch((error) => {
console.log("err", error);
alert(t("something-went-wrong-mssg"));
});
});
} else {
alert(t("password-update-alert-2"));
}
})
.catch((error) => {
alert(t("password-update-alert-3"));
console.error("Error while logging in user", error);
});
if (lengthValid && caseDigitValid && specialCharValid) {
Parse.User.logIn(localStorage.getItem("userEmail"), currentpassword)
.then(async (user) => {
if (user) {
const User = new Parse.User();
const query = new Parse.Query(User);
await query.get(user.id).then((user) => {
// Updates the data we want
user.set("password", newpassword);
user
.save()
.then(async () => {
let _user = user.toJSON();
if (_user) {
await Parse.User.become(_user.sessionToken);
localStorage.setItem("accesstoken", _user.sessionToken);
}
setCurrentPassword("");
setnewpassword("");
setconfirmpassword("");
alert(t("password-update-alert-1"));
})
.catch((error) => {
console.log("err", error);
alert(t("something-went-wrong-mssg"));
});
});
} else {
alert(t("password-update-alert-2"));
}
})
.catch((error) => {
alert(t("password-update-alert-3"));
console.error("Error while logging in user", error);
});
}
} else {
alert(t("password-update-alert-4"));
}
Expand Down Expand Up @@ -80,34 +109,93 @@ function ChangePassword() {
<label htmlFor="newpassword" className="text-xs block ml-1">
{t("new-password")}
</label>
<input
type="password"
name="newpassword"
value={newpassword}
onChange={(e) => setnewpassword(e.target.value)}
className="op-input op-input-bordered op-input-sm text-xs w-full"
placeholder={t("new-password")}
onInvalid={(e) => e.target.setCustomValidity(t("input-required"))}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
<div className="relative">
<input
type={showNewPassword ? "text" : "password"}
name="newpassword"
value={newpassword}
onChange={(e) => setnewpassword(e.target.value)}
className="op-input op-input-bordered op-input-sm text-xs w-full"
placeholder={t("new-password")}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
<span
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer text-base-content`}
onClick={toggleNewPasswordVisibility}
>
{showNewPassword ? (
<i className="fa fa-eye-slash" /> // Close eye icon
) : (
<i className="fa fa-eye" /> // Open eye icon
)}
</span>
</div>
</div>
<div>
<label htmlFor="newpassword" className="text-xs block ml-1">
<label htmlFor="confirmpassword" className="text-xs block ml-1">
{t("confirm-password")}
</label>
<input
type="password"
name="confirmpassword"
className="op-input op-input-bordered op-input-sm text-xs w-full"
value={confirmpassword}
onChange={(e) => setconfirmpassword(e.target.value)}
placeholder={t("confirm-password")}
onInvalid={(e) => e.target.setCustomValidity(t("input-required"))}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
<div className="relative">
<input
type={showConfirmPassword ? "text" : "password"}
name="confirmpassword"
className="op-input op-input-bordered op-input-sm text-xs w-full"
value={confirmpassword}
onChange={handlePasswordChange}
placeholder={t("confirm-password")}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
<span
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer text-base-content`}
onClick={toggleConfirmPasswordVisibility}
>
{showConfirmPassword ? (
<i className="fa fa-eye-slash" /> // Close eye icon
) : (
<i className="fa fa-eye" /> // Open eye icon
)}
</span>
</div>
</div>
{confirmpassword.length > 0 && (
<div className="mt-1 text-[11px]">
{newpassword.length > 0 && (
<p
className={`${newpassword === confirmpassword ? "text-green-600" : "text-red-600"} text-[11px] mt-1`}
>
{newpassword === confirmpassword ? "✓" : "✗"}{" "}
{t("password-match-length")}
</p>
)}
<p
className={`${lengthValid ? "text-green-600" : "text-red-600"}`}
>
{lengthValid ? "✓" : "✗"} {t("password-length")}
</p>
<p
className={`${
caseDigitValid ? "text-green-600" : "text-red-600"
}`}
>
{caseDigitValid ? "✓" : "✗"} {t("password-case")}
</p>
<p
className={`${
specialCharValid ? "text-green-600" : "text-red-600"
}`}
>
{specialCharValid ? "✓" : "✗"} {t("password-special-char")}
</p>
</div>
)}
<button
type="submit"
className="op-btn op-btn-primary shadow-md mt-2"
Expand Down