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: note taking example #286

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

feat: note taking example #286

wants to merge 13 commits into from

Conversation

weboko
Copy link
Contributor

@weboko weboko commented Nov 17, 2023

Example of notes:

This app has two screens:

  • create note;
  • view note;

There is some problem with routing in Next.js so not merging yet.

@weboko weboko marked this pull request as ready for review November 23, 2023 16:30
@weboko weboko requested a review from a team as a code owner November 23, 2023 16:30
Copy link
Contributor

@danisharora099 danisharora099 left a comment

Choose a reason for hiding this comment

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

lgtm. some generic structuring/readability nitpicks.

examples/flush-notes/README.md Outdated Show resolved Hide resolved
Comment on lines 51 to 75
const useEditNote = () => {
const [state, setState] = React.useState<string>("");

const onNoteChange = (event: React.FormEvent<HTMLTextAreaElement>) => {
setState(event?.currentTarget?.value);
};

return {
note: state,
onNoteChange,
};
};

const usePassword = () => {
const [password, setPassword] = React.useState<string>();

const onPasswordChange = (event: React.FormEvent<HTMLInputElement>) => {
setPassword(event?.currentTarget?.value);
};

return {
password,
onPasswordChange,
};
};
Copy link
Contributor

Choose a reason for hiding this comment

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

we can move all hooks to a dedicated directory for readability

Copy link
Contributor Author

Choose a reason for hiding this comment

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

tbh I think here it's better to keep in the same file as it is strongly connected and hooks are dead simple

examples/flush-notes/src/app/page.tsx Outdated Show resolved Hide resolved
examples/flush-notes/src/app/Loading.tsx Outdated Show resolved Hide resolved
Comment on lines 22 to 23
export const useWaku = () => {
const { status, waku } = React.useContext(WakuContext);
Copy link
Contributor

Choose a reason for hiding this comment

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

can we use the existing react-hooks?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nice spot, I think we can later but not now as I am using RC version of js-waku

Copy link
Contributor

Choose a reason for hiding this comment

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

we can remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so as it is directly used by NextJS

examples/flush-notes/src/services/notes.ts Outdated Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

hm perhaps services should be called utils or lib? stays in consistency with other examples

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I prefer services as it is something that has coherent functionality over some theme: note, waku etc

examples/flush-notes/src/services/waku.ts Outdated Show resolved Hide resolved
Comment on lines +3 to +8
export enum WakuStatus {
Initializing = "Initializing...",
WaitingForPeers = "Waiting for peers...",
Connected = "Connected",
Failed = "Failed to initialize(see logs)",
}
Copy link
Contributor

Choose a reason for hiding this comment

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

indifferent for now as we don't have many. but i'd expect types/interfaces to be in a dedicated types file/subdir and keep constants separate

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree about a need to cluster types in one place if they are generic, if they are strongly bound to one place - they should be located in that place (one file)

for enum it is tricky as it can be a type and can be a variable as it gets into end bundle and is not ephemeral as just types. so in this context it is a const as it was used in UI directly for rendering message

Copy link
Collaborator

@fryorcraken fryorcraken left a comment

Choose a reason for hiding this comment

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

We need to reflect best practices in our examples.

  • Usage of efficient encoding: bandwidth is the scarce resource on the Waku network, we should recommend to only use efficient encoding methods over the wire such as proto.
  • encryption by default: if encryption is used, then all messages should be encrypted. If only "some" messages are encrypted then you generally reduce the anonymity properties of the users.

What I would recommend is:

  • always encrypt the whole message
  • The URL contains the symkey or not
    • if it contains the symkey, use it to encrypt/decrypt
    • if it does not contain a key, then the user is using a password.

This way, there is no different to the user whether its encrypted or whether the key is in the url of the note.

: { id: generateRandomString(), content, iv: undefined };

await waku.send(this.encoder, {
payload: utf8ToBytes(JSON.stringify(note)),
Copy link
Collaborator

Choose a reason for hiding this comment

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

JSON strings over the wire is bigger than protobuf. We should prefer protobuf (or other efficient byte encoding) in examples to discourage devs to send large messages.

const symmetricKey = toEncrypt ? generateSymmetricKey() : undefined;
const note = toEncrypt
? await this.encryptNote(content, symmetricKey)
: { id: generateRandomString(), content, iv: undefined };
Copy link
Collaborator

Choose a reason for hiding this comment

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

It may be interesting to actually encrypt all notes by default.

Selective encryption should not be recommended as it is generally reduce anonymity properties by reducing the anonymity set.

}

const iv = hexToBytes(note.iv);
const symmetricKey = hexToBytes(password);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not recommend practice. PBKDF2 is generally the recommend practice to convert a password to a key.

@fryorcraken
Copy link
Collaborator

Not sure I mentioned but I think it's an awesome app idea and I think it can demonstrate how to do permission on a decentralized system.:

  • Alice creates note and private key KPO for note owner and symmetric key SK for encryption
  • Alice gives the note to Bob so he can view it, she provides SK and getPublicKey(KPO) to Bob.
  • When alice does an update, she sign the update (or new revision) of the note with KPO so Bob knows the update is legit
  • Alice wants to make Carole an editor of the note, Carole generate new private key KPE and send public key getPublicKey(KPE) to Alice.
  • Alice sends update "add editor" with getPublicKey(KPE) so Bob is aware that Carole's update should be taken in account.
  • Carole can now do an update on the note and sign it with KPE.

- Notes are fully encrypted using Waku Message version 1 (no metadata leak)
- Notes are always encrypted, key is part of the URL
- Using standard uuid v4 from browser API to generate ID
- upgraded deps to fix a bug
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