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

feat(cred-server): generate custom credential schemas #751

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from

Conversation

jorgenavben
Copy link
Member

@jorgenavben jorgenavben commented Oct 1, 2024

Description

This pull request introduces new functionality for the credential issuance server, focusing on the creation and management of custom ACDC schemas. Key changes include:

  • Custom Schema Creation and Deletion: Added endpoints to allow for the creation of custom ACDC schemas as well as the ability to delete them when needed.
  • Dynamic Schema Adaptation: Updated the issuance and request credential pages to dynamically adapt based on different schemas, ensuring flexibility for varied credential formats.
  • Local Database Integration: Implemented a new local database within the credential server backend to securely store and manage the newly created custom schemas.

Checklist before requesting a review

Issue ticket number and link

  • This PR has a valid ticket number or issue: link

Security

  • No secrets are being committed (i.e. credentials, PII)
  • This PR does not have any significant security implications

Code Review

  • There is no unused functionality or blocks of commented out code (otherwise, please explain below)
  • In addition to this PR, all relevant documentation (e.g. Confluence) and architecture diagrams (e.g. Miro) were updated

image

@jorgenavben jorgenavben self-assigned this Oct 18, 2024
@jorgenavben jorgenavben changed the title feat(cred-server): added endpoint to saidify schema feat(cred-server): generate custom cretential schemas Nov 8, 2024
@jorgenavben jorgenavben changed the title feat(cred-server): generate custom cretential schemas feat(cred-server): generate custom credential schemas Nov 8, 2024
@jorgenavben jorgenavben marked this pull request as ready for review November 8, 2024 13:26
@@ -223,6 +225,7 @@ const ACDC_SCHEMAS = {
description: "LE Issuer AID",
type: "string",
format: "ISO 17442",
customizable: true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that when you go to the issue credential page in the UI that field will show up as an input field for the user to fill before they issue a credential. Now that the schemas are not hardcoded anymore I had to come up with an idea to make the UI aware of the data that the user will be able to input before issue a credential.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, we shouldn't be changing the actual schema though. Everything is customizable by the user in the a block besides a.i and a.dt.

}
}

export default Lmdb.getInstance();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're just going to export a single instance, we don't need to do the whole private constructor thing. You could just do

const database = new Database();
export { database }

@@ -0,0 +1,39 @@
import { open, RootDatabase } from "lmdb";

class Lmdb {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually it's better to not name these kinds of classes based on the underlying tech. So Database would be more appropriate so that you could change from lmdb to something else without many code changes across the repo.

});
}

public static getInstance(): Lmdb {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too important but no need to put public as its default. You can also use static get instance so it's more like db.instance instead of db.getInstance()

await this.db.put(key, value);
} catch (error) {
console.error("Error putting data in LMDB:", error);
throw error;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no point catching and re-throwing if you're just logging. It's cleaner to just fully remove the try catch and let it throw, you'll get all the details.

return res.status(404).send("Schema for given SAID not found");
}

const data = schema.schema;
if (!data) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, we should just assume it has schema if we always store it like that. 404 implies that it's not there

async saveSchema(schema: any, label?: string): Promise<void> {
const { saidifiedSchema, customizableKeys } =
await this.signifyApi.saidifySchema(schema, label);
let schemas = await lmdb.get(SCHEMAS_KEY);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to do something like the key as schema:<schemaId> and then store them individually. Rather than a single big object for all schemas.

if (!data) {
const schemas = await lmdb.get(SCHEMAS_KEY);
if (!schemas) {
return res.status(404).send("No schemas found");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will change based on my other comment, but yeah no need for this. Just the 404 below

services/credential-server-ui/src/App.tsx Outdated Show resolved Hide resolved

async saidifySchema(schema: any, label?: string): Promise<any> {
const customizableKeys: { [key: string]: any } = {};
const removeCustomizables = (obj: any, path: string[] = []): any => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I need to understand this customizable part first before I understand what's happening here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioned in other comments but I can provide more information if needed :)

Copy link
Contributor

@sdisalvo-crd sdisalvo-crd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could have flagged a lot more, but instead I just left a few comments that may help as general guidelines as I understand that I am only taking a first look at this now and in order to keep this ui work consistent with the rest of the work done in this repo we need to re-do it entirely and it's not a matter of just adding some small fix here.

setDefaultCredentialType("");
}
} catch (error) {
console.log(`Error fetching schema list: ${error}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see all errors are thrown in the console. It would be nice if we followed what we do in the app and show <ErrorMessage message={errorMessage}/> instead. Unless it's something hacky that we want to know as devs, in that case why not just throw a proper error.

renderInput={(params) => (
<TextField
{...params}
label="Search by connection name or ID"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if we had a i18n file with all text in it.

<Button
startIcon={<RefreshIcon />}
onClick={handleGetContacts}
style={{ height: "100%" }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline style is old school and usually never recommended.

xs={11}
>
<FormControl fullWidth>
<InputLabel id="credential_type">Credential Type</InputLabel>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is generally recommended to use lowercase and hyphens for classes, camelCase for IDs.

</Grid>
<Grid
item
xs={11}
Copy link
Contributor

@sdisalvo-crd sdisalvo-crd Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why we are using something different (mui?) than what we already have in the app for handling styles. I would suggest to keep it consistent, instead of adopting a whole different system, however I understand this entire tool is already built so this will just be a thought.

@@ -19,6 +19,8 @@ const NavBar: React.FC = () => {
const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(
null
);
const [anchorElCredentials, setAnchorElCredentials] =
React.useState<null | HTMLElement>(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just import React once, at the top of the file, and then avoid repeating React. every time you need to call a method.

Credentials
</Button>
<Menu
id="credentials-menu"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ID is now using dash, the one before was using an underscore. I would check that all of the IDs and class names are following the convention I mentioned before and keep it consistent.

}) => {
useEffect(() => {
if (visible) {
const timer = setTimeout(onClose, 3000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to assign that numeric value to a constant.

Comment on lines +94 to +104
style={{ marginBottom: "30px" }}
>
<div
style={{
display: "flex",
gap: "10px",
marginBottom: "10px",
alignItems: "center",
}}
>
<div style={{ display: "flex", gap: "10px", flex: 1 }}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to assign class names and add all style into a dedicated stylesheet. This apply to all inline styles in the entire folder. Please have a look around so I won't need to repeat this comment.

Comment on lines +394 to +395
<h4>Attributes</h4>
<Tooltip title="A top-level field map within an ACDC that provides a property of an entity that is inherent or assigned to the entity.">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to have al text in a i18n file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants