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: relocation of ctype config #78

Merged
merged 15 commits into from
Mar 13, 2024
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ DAPP_DID_MNEMONIC=
DAPP_DID_URI=
DAPP_NAME=
JWT_SIGNER_SECRET=

# Email credentials from SocialKYC on the KILT testnet Peregrine
CTYPE_HASH=0x3291bb126e33b4862d421bfaa1d2f272e6cdfc4f96658988fbcffea8914bd9ac
rompemoldes marked this conversation as resolved.
Show resolved Hide resolved
TRUSTED_ATTESTERS=did:kilt:4pehddkhEanexVTTzWAtrrfo2R7xPnePpuiJLC7shQU894aY
REQUIRED_PROPERTIES=Email
10 changes: 5 additions & 5 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"semi": false,
"trailingComma": "none",
"singleQuote": true,
"tabWidth": 2
}
"semi": false,
"trailingComma": "none",
"singleQuote": true,
"tabWidth": 2
}
4 changes: 2 additions & 2 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ nodeLinker: node-modules

plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
spec: '@yarnpkg/plugin-workspace-tools'
- path: .yarn/plugins/@yarnpkg/plugin-version.cjs
spec: "@yarnpkg/plugin-version"
spec: '@yarnpkg/plugin-version'

yarnPath: .yarn/releases/yarn-3.6.1.cjs
38 changes: 31 additions & 7 deletions README.md
aybarsayan marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,6 @@ For a user to log in with KILT, it requires:
- one of the cTypes accepted by the dApp.
- issued by one of the dApps _trusted attesters_.

- In this demo, as a default, the dApp requests a credential that contains an email address.
For that we rely on **SocialKYC** to issue email credentials after verifying the user owns it.
Get your

- [credential attested by **SocialKYC** on **_Peregrine_** here](https://test.socialkyc.io).
- [credential attested by **SocialKYC** on **_Spiritnet_** here](https://socialkyc.io).

## Steps to launch the dApp locally

1. [Clone repository and **install** all necessary modules.](#Installation)
Expand Down Expand Up @@ -129,6 +122,37 @@ The following variables are required:
- `DAPP_DID_URI` = _This is the URI of the Kilt DID that identifies your dApp_
- `DAPP_NAME` = _This should be a custom name for your dApp_
- `JWT_SIGNER_SECRET` = _This is secret key (string) that signs the Json-Web-Tokens before saving them in the Cookies_
- `CTYPE_HASH` = _This is the type of credential (CType) your dApp will request from users for login. If you want to specify more than one CType, you can do so by adding a '/' sign between them_
- `TRUSTED_ATTESTERS` = _This is a list of attester DIDs (CSV, separated by ','). Only credentials issued by these attesters will be considered valid. If you are using more than one CType, indicate the groups of trusted attesters by respectively separating them with a '/' sign._
- `REQUIRED_PROPERTIES` = _This is a subset of CType properties (CSV, separated by ',') required to be exposed on credential presentation. If you are using more than one CType, indicate the groups of required properties by respectively separating them with a '/' sign._

### Info about Example/Recommended cTypes

This table provides information on recommended cTypes for SocialKYC credential issuance. SocialKYC is a platform that issues credentials based on user social media presence. The cType-hash is consistent across both Spiritnet and Peregrine to ensure interoperability and consistent verification across the KILT network by using universal identifiers stored on archive nodes.

#### SocialKYC on Spiritnet:

did:kilt:4pnfkRn5UurBJTW92d9TaVLR2CqJdY4z5HPjrEbpGyBykare

#### SocialKYC on Peregrine:

did:kilt:4pehddkhEanexVTTzWAtrrfo2R7xPnePpuiJLC7shQU894aY

Here are the cTypes recommended for SocialKYC:

| Title | CTYPE_HASH | SocialKYC on Spiritnet | SocialKYC on Peregrine | Properties |
| -------------- | ------------------------------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ---------------------------------------- |
| Email | 0x3291bb126e33b4862d421bfaa1d2f272e6cdfc4f96658988fbcffea8914bd9ac | [prod. Spiritnet](#SocialKYC-on-Spiritnet) | [prod. Peregrine](#SocialKYC-on-Peregrine) | Email |
| Twitter | 0x47d04c42bdf7fdd3fc5a194bcaa367b2f4766a6b16ae3df628927656d818f420 | [prod. Spiritnet](#SocialKYC-on-Spiritnet) | [prod. Peregrine](#SocialKYC-on-Peregrine) | Twitter |
| Discord | 0xd8c61a235204cb9e3c6acb1898d78880488846a7247d325b833243b46d923abe | [prod. Spiritnet](#SocialKYC-on-Spiritnet) | [prod. Peregrine](#SocialKYC-on-Peregrine) | Discriminator, User ID, Username |
| GitHub | 0xad52bd7a8bd8a52e03181a99d2743e00d0a5e96fdc0182626655fcf0c0a776d0 | [prod. Spiritnet](#SocialKYC-on-Spiritnet) | [prod. Peregrine](#SocialKYC-on-Peregrine) | GitHubUsername, Username |
| Twitch | 0x568ec5ffd7771c4677a5470771adcdea1ea4d6b566f060dc419ff133a0089d80 | [prod. Spiritnet](#SocialKYC-on-Spiritnet) | [prod. Peregrine](#SocialKYC-on-Peregrine) | User ID, Username |
| Telegram | 0xcef8f3fe5aa7379faea95327942fd77287e1c144e3f53243e55705f11e890a4c | [prod. Spiritnet](#SocialKYC-on-Spiritnet) | [prod. Peregrine](#SocialKYC-on-Peregrine) | First name, Last name, User ID, Username |
| YoutubeChannel | 0x329a2a5861ea63c250763e5e4c4d4a18fe4470a31e541365c7fb831e5432b940 | [prod. Spiritnet](#SocialKYC-on-Spiritnet) | [prod. Peregrine](#SocialKYC-on-Peregrine) | Channel ID, Channel Name |

Note: We only recommend these cTypes and properties for SocialKYC verification. Users are advised to select the appropriate properties based on their verification needs.

Additionally, for access to a broader range of CType Hashes, consider visiting the [CType Hub](https://ctypehub.galaniprojects.de/).

### Setup your environment

Expand Down
20 changes: 11 additions & 9 deletions backend/src/access/login.ts
aybarsayan marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { Response, Request } from 'express'

import { emailRequest } from '../credentials/listOfRequests'
import { cTypesToRequest } from '../credentials/cTypesToRequest'
import { buildCredentialRequest } from '../credentials/buildCredentialRequest'
import { verifySubmittedCredential } from '../credentials/verifySubmittedCredential'

import { setAccessCookie } from './setAccessCookie'

// Here you can set which type of credential (cType) your dApp will request users to login.
// You can change it by importing a different one from the list.
const requestedCTypeForLogin = emailRequest

/** First half of the login with credentials.*/
export async function buildLoginCredentialRequest(
request: Request,
Expand All @@ -19,7 +15,7 @@ export async function buildLoginCredentialRequest(
const encryptedCredentialRequest = await buildCredentialRequest(
request,
response,
requestedCTypeForLogin
cTypesToRequest
)
// With this, the extension will know what kind of credential to share
response.status(200).send(encryptedCredentialRequest)
Expand All @@ -37,13 +33,19 @@ export async function handleLoginCredentialSubmission(
const verifiedCredential = await verifySubmittedCredential(
request,
response,
requestedCTypeForLogin
cTypesToRequest
)

// Send a little something to the frontend, so that the user interface can display who logged in.
// The frontend can't read the encrypted credential; only the backend has the key to decrypt it.
// "Email" is capitalized on this cType schema
const plainUserInfo = verifiedCredential.claim.contents.Email
const claimContents = verifiedCredential.claim.contents
// Check if any properties have been provided. If not, send 'Anonymous User' to display on the frontend.
// If any property exists, send object's first attribute value,
// ensuring compatibility with any 'cType'.
const plainUserInfo =
Object.keys(claimContents).length === 0
? 'Anonymous User'
: claimContents[Object.keys(claimContents)[0]]

console.log(
'Decrypted User Info that we are passing to the frontend:',
Expand Down
5 changes: 5 additions & 0 deletions backend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export const DAPP_DID_URI = loadEnv('DAPP_DID_URI') as Kilt.DidUri
export const DAPP_NAME = process.env.DAPP_NAME ?? 'Web3-Login-Demo'
export const JWT_SIGNER_SECRET = loadEnv('JWT_SIGNER_SECRET')

// Configurable Credential types
export const CTYPE_HASH = loadEnv('CTYPE_HASH')
export const TRUSTED_ATTESTERS = loadEnv('TRUSTED_ATTESTERS')
export const REQUIRED_PROPERTIES = loadEnv('REQUIRED_PROPERTIES')

export let DAPP_ACCOUNT_ADDRESS: string

function loadEnv(name: string) {
Expand Down
44 changes: 44 additions & 0 deletions backend/src/credentials/cTypesToRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as Kilt from '@kiltprotocol/sdk-js'

import { CTYPE_HASH, REQUIRED_PROPERTIES, TRUSTED_ATTESTERS } from '../config'

/** Establish the types of credentials (cTypes) that our dApp will request from users to log in,
* identify which properties are necessary, and specify which attesters we trust.
*
* These settings are defined by the constants imported from the config file.
* Modify the `env` file to adapt it to your preferences.
*/

const cTypeHashes = CTYPE_HASH.split('/').map((s) => s.trim())

const trustedAttesterList = TRUSTED_ATTESTERS.split('/').map((s) => s.trim())

const requiredPropertiesList = REQUIRED_PROPERTIES.split('/').map((s) =>
s.trim()
)

const cTypes: {
cTypeHash: `0x${string}`
trustedAttesters: Kilt.DidUri[]
requiredProperties: string[]
}[] = []

for (let i = 0; i < cTypeHashes.length; i++) {
const trustedAttesters = trustedAttesterList[i].split(',').map((s) => {
const trimmed = s.trim()
Kilt.Did.validateUri(trimmed)
return trimmed as Kilt.DidUri
})
const requiredProperties = requiredPropertiesList[i]
.split(',')
.map((s) => s.trim())
const cType = {
cTypeHash: cTypeHashes[i] as `0x${string}`,
trustedAttesters,
requiredProperties
}
cTypes.push(cType)
}
export const cTypesToRequest: Kilt.IRequestCredentialContent = {
cTypes
}
42 changes: 0 additions & 42 deletions backend/src/credentials/listOfRequests.ts

This file was deleted.

28 changes: 14 additions & 14 deletions frontend/public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"short_name": "Web3 Login",
"name": "KILT Web3 Login",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
"short_name": "Web3 Login",
"name": "KILT Web3 Login",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
5 changes: 2 additions & 3 deletions frontend/src/components/Card.module.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

.card {
padding: 24px;
background: rgba(255, 255, 255, 0.31);
Expand All @@ -8,12 +7,12 @@
-webkit-backdrop-filter: blur(7.1px);
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 8px;
color: white;
color: white;
display: inline-flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: normal;
min-width: 500px;
}
}
2 changes: 1 addition & 1 deletion frontend/src/components/Logo.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
display: inline-block;
color: white;
font-size: 18px;
}
}
51 changes: 49 additions & 2 deletions scripts/genesisEnvironmentVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ const {
// This should be a custom name for your dApp
DAPP_NAME,
// This is secret key (string) that signs the Json-Web-Tokens before saving them in the Cookies
JWT_SIGNER_SECRET
JWT_SIGNER_SECRET,
// This is the CType hash for Email credentials from SocialKYC
CTYPE_HASH,
// These are the trusted attesters for the CType
TRUSTED_ATTESTERS,
// These are the required properties for the CType
REQUIRED_PROPERTIES
} = process.env

async function main() {
Expand Down Expand Up @@ -53,7 +59,10 @@ async function main() {
DAPP_DID_MNEMONIC,
DAPP_DID_URI,
DAPP_NAME,
JWT_SIGNER_SECRET
JWT_SIGNER_SECRET,
CTYPE_HASH,
TRUSTED_ATTESTERS,
REQUIRED_PROPERTIES
}

// find the first element in the object "stairs" that still has an undefined value.
Expand Down Expand Up @@ -110,6 +119,18 @@ async function main() {
case 7:
imploreJwtSecretKey()
break
case 8:
imploreCtypeHash()
break
// ask you to choose a Ctype Hash
case 9:
imploreTrustedAttesters()
break
// ask you to choose a Ctype Hash
case 10:
imploreRequestedProperties()
break
// ask you to choose a Ctype Hash
// if (step = -1):
default:
console.log(
Expand Down Expand Up @@ -240,5 +261,31 @@ function imploreJwtSecretKey() {
)
}

function imploreCtypeHash() {
console.log(
'Please provide the CType Hash(es) inside the .env file using this constant name:.\n',
'Your dApp will only accept credentials of this given Claim Type(s).',
`CTYPE_HASH={CType IDs your dApp consider valid}\n`,
`If you wish to use the default Email Credential settings, please add the following line to your .env file:\n`,
`CTYPE_HASH=0x3291bb126e33b4862d421bfaa1d2f272e6cdfc4f96658988fbcffea8914bd9ac\n`
)
}
function imploreTrustedAttesters() {
console.log(
'Please provide a list for your Trusted Attesters inside the .env file using this constant name: \n',
`TRUSTED_ATTESTERS={lists of trusted attesters}\n`,
`If you wish to use the default Email Credential settings, please add the following line to your .env file:\n`,
`TRUSTED_ATTESTERS=did:kilt:4pehddkhEanexVTTzWAtrrfo2R7xPnePpuiJLC7shQU894aY\n`
)
}
Comment on lines +273 to +280
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
function imploreTrustedAttesters() {
console.log(
'Please provide a list for your Trusted Attesters inside the .env file using this constant name: \n',
`TRUSTED_ATTESTERS={lists of trusted attesters}\n`,
`If you wish to use the default Email Credential settings, please add the following line to your .env file:\n`,
`TRUSTED_ATTESTERS=did:kilt:4pehddkhEanexVTTzWAtrrfo2R7xPnePpuiJLC7shQU894aY\n`
)
}
function imploreTrustedAttesters() {
console.log(
'Please provide a list for your Trusted Attesters inside the .env file using this constant name: \n',
'Your dApp will only accept credentials issued by one of this attesters.',
`TRUSTED_ATTESTERS={lists of trusted attesters}\n`,
`If you wish to use the default and accept Credentials issued by SocialKYC.io on Peregrine, please add the following line to your .env file:\n`,
`TRUSTED_ATTESTERS=did:kilt:4pehddkhEanexVTTzWAtrrfo2R7xPnePpuiJLC7shQU894aY\n`
)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done at: 4868513

function imploreRequestedProperties() {
console.log(
'Please provide a list of Required Properties inside the .env file using this constant name: \n',
`REQUIRED_PROPERTIES={lists of Properties users should be Required to disclose}\n`,
`If you wish to use the default Email Credential settings, please add the following line to your .env file:\n`,
`REQUIRED_PROPERTIES=Email\n`
)
}

//run the code
main()
Loading