diff --git a/app/src/app/registries/registry/freeid/freeid.component.html b/app/src/app/registries/registry/freeid/freeid.component.html index b19d90b7..98cca91e 100644 --- a/app/src/app/registries/registry/freeid/freeid.component.html +++ b/app/src/app/registries/registry/freeid/freeid.component.html @@ -1,21 +1,299 @@ -

Unchain Your Identity in the New Free World

+ + + privacy_tip  About +
+ + +

Unchain Your Identity in the New Free World

-

- FreeID is a revolutionary, decentralized identity system designed for individuals who value freedom and autonomy - worldwide. Developed by the FreeID Foundation, established under the auspices of the World Voluntaryist Organization, - FreeID offers a global solution for those seeking sovereignty over their personal identity. Serving as a parallel - identity system within the New Free World, FreeID empowers individuals with a secure and cryptographically protected - means of asserting their autonomy. -

+

+ FreeID is a revolutionary, decentralized identity system designed for individuals who value freedom and + autonomy worldwide. Developed by the FreeID Foundation, established under the auspices of the World + Voluntaryist Organization, FreeID offers a global solution for those seeking sovereignty over their personal + identity. Serving as a parallel identity system within the New Free World, FreeID empowers individuals with + a secure and cryptographically protected means of asserting their autonomy. +

-

- FreeID is issued by the FreeID Foundation, a non-profit organization dedicated to promoting individual sovereignty. -

+

+ FreeID is issued by Verification Services approved by the World Voluntaryist Organisation, a non-profit + organization dedicated to promoting individual sovereignty. +

-

Official Issuer DID: did:dht:mo7am9cz6qrjwoc4kapffeue9kjw6igdh9dmqd3ywdif6qa7ju4o

+

Approved Verification Services

-

- Apply for FreeID -

+ @for(service of services; track service) { +
+
+ {{ service.name }} +
+
Identifier: {{ service.did }}
+
{{ service.location }}
+ +
+ } + + + + +
+
+ + +
+
+ + + safety_check  Apply for FreeID + + +
+

Apply for FreeID

+ + + +

+ Different Verification Services are available to issue FreeID. Please select a Verification Service from the + list in the About page. +

+ +

+ Individual Verification Services might have different requirements and processes for issuing FreeID. Please + visit the website of the Verification Service you have selected for more information. +

+ +

The base requirements is same for all approved Verification Services.

+
+
+ +

Base Requirements

+ + + +

+ Physical Presence: The applicant for FreeID must be physically present with the + Verification Service trusted verifier. It is not possible to perform verifiation online. +

+ +

+ Sign: The Voluntaryist Covernant. + Open the Mini App to sign. +

+ +

+ Name: Your name that you choose, it can be a pseudonym or a real name. It does not need to + be same as your birth name. +

+ +

+ Birth date: Your birth date can be choosen from up to two months prior and two months after + your actual birth date. This is to obfuscate and disconnect your new identity from your old identity. You + must provide proof of birth. +

+ +

+ Sex: You must provide your sex in the form of birth sex. This is for health and security + reasons. +

+ +

+ Photograph: You must be photographed on the day of application. Photograph must be captured + by the Verification Service and follow the guidelines for good identification photograph. +

+ +

Identifier: You must provide a decentralized identifier (DID) that you control.

+
+
+ + + + @if (lookupSigned !== undefined) { +

+ + + Signature Status + + +

+ @if (lookupSigned) { + verified_user + } @else { + gpp_bad + } +

+

The identity with the following DID has @if (!lookupSigned) { not } signed the convenant:

+

+ {{ did }} +

+ + +

+ } +
+
+ + + policy  Validate + +
+

Validate FreeID Credential

+ + + + + + + @if (lookupSigned !== undefined) { +

+ + + Signature Status + + +

+ @if (lookupSigned) { + verified_user + } @else { + gpp_bad + } +

+

The FreeID credential with the following DID is @if (!lookupSigned) { not } valid:

+

+ {{ did }} +

+ + +

+ } +
+
+
diff --git a/app/src/app/registries/registry/freeid/freeid.component.scss b/app/src/app/registries/registry/freeid/freeid.component.scss index 41d60c01..3410a365 100644 --- a/app/src/app/registries/registry/freeid/freeid.component.scss +++ b/app/src/app/registries/registry/freeid/freeid.component.scss @@ -1,3 +1,16 @@ .freeid-logo { max-height: 64px; + margin: 1.4em 1em 1em 2em; +} + +.verification-service { + margin-bottom: 1em; +} + +.did-input { + width: calc(100% - 40px); +} + +.signature-icon { + font-size: 4em; } diff --git a/app/src/app/registries/registry/freeid/freeid.component.ts b/app/src/app/registries/registry/freeid/freeid.component.ts index e88172e7..44ad8b4c 100644 --- a/app/src/app/registries/registry/freeid/freeid.component.ts +++ b/app/src/app/registries/registry/freeid/freeid.component.ts @@ -1,20 +1,179 @@ -import { Component, inject } from '@angular/core'; +import { Component, effect, inject } from '@angular/core'; import { LayoutService } from '../../../layout.service'; import { MatButtonModule } from '@angular/material/button'; +import { CommonModule } from '@angular/common'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatCardModule } from '@angular/material/card'; +import { MatIconModule } from '@angular/material/icon'; +import { MatTabsModule } from '@angular/material/tabs'; +import { AppService } from '../../../app.service'; +import { IdentityService } from '../../../identity.service'; +import { credential } from '../../../../protocols'; +import { VerifiableCredential } from '@web5/credentials'; +import { RouterModule } from '@angular/router'; @Component({ selector: 'app-freeid', standalone: true, - imports: [MatButtonModule], + imports: [ + RouterModule, + MatButtonModule, + CommonModule, + MatInputModule, + MatFormFieldModule, + FormsModule, + ReactiveFormsModule, + MatCardModule, + MatIconModule, + MatTabsModule, + ], templateUrl: './freeid.component.html', styleUrl: './freeid.component.scss', }) export class FreeIDComponent { + // Source: https://github.com/WorldVoluntaryistOrganisation/VerificationServices/blob/main/services.json + services = [ + { + did: '123', + name: 'Liberstad FreeID Office', + location: 'Liberstad, Norway', + website: 'https://freeid.me', + }, + { + did: '321', + name: 'Montelibero Verification Office', + location: 'Montelibero City, Bar, Montenegro', + website: 'https://montelibero.org', + }, + ]; + + vcType = 'IdentityCredential'; + + app = inject(AppService); + + identity = inject(IdentityService); + layout = inject(LayoutService); + loading = false; + + signed = false; + + lookupSigned: boolean | undefined = undefined; + + did = ''; + constructor() { - this.layout.marginOn(); + this.layout.marginOff(); + + effect(() => { + if (this.app.initialized()) { + this.load(); + } + }); + } + + async load() { + var { records: vcRecords } = await this.identity.web5.dwn.records.query({ + message: { + filter: { + schema: this.vcType, + dataFormat: credential.format, + }, + }, + }); + + if (vcRecords!.length > 0) { + this.signed = true; + } + } + + async sign() { + this.loading = true; + + const vc = await VerifiableCredential.create({ + type: 'WorldVoluntaryistOrganisationCredential', + issuer: this.identity.did, + subject: this.identity.did, + data: { + signed: 'The Voluntaryist Covenant', + version: '1.0', + hash: '856da8db8fec583255fa09cc19c64a93d44cba7a4d6c408282643fc581ae6c4b', + }, + }); + + const did = await this.identity.activeAgent().did.get({ didUri: this.identity.did }); + console.log('DID:', did); + + const identities = await this.identity.activeAgent().identity.list(); + console.log('Identitites:', identities); + + const bearerDid = await this.identity.activeAgent().identity.get({ didUri: this.identity.did }); + + console.log('this.identity.did:', this.identity.did); + console.log('Bearer DID:', bearerDid); + console.log('Active Agent:', this.identity.activeAgent()); + + const vc_jwt = await vc.sign({ did: bearerDid!.did }); + + const { record } = await this.identity.web5.dwn.records.create({ + data: vc_jwt, + message: { + schema: this.vcType, + dataFormat: credential.format, + published: true, + }, + }); + + console.log('VC RECORD:', record); + + const { status } = await record!.send(this.identity.did); + console.log('Record sent:', status, record); + + this.signed = true; } - apply() {} + async lookup() { + this.lookupSigned = undefined; + + const { records } = await this.identity.web5.dwn.records.query({ + from: this.did, + message: { + filter: { + schema: this.vcType, + dataFormat: credential.format, + }, + }, + }); + + console.log('VC RECORDS:', records); + + // TODO: Here we should actually validate the VC. + if (records!.length > 0) { + this.lookupSigned = true; + } else { + this.lookupSigned = false; + } + } + + async withdraw() { + var { records: vcRecords } = await this.identity.web5.dwn.records.query({ + message: { + filter: { + schema: this.vcType, + dataFormat: credential.format, + }, + }, + }); + + for (const record of vcRecords!) { + await record.delete(); + record.send(this.identity.did); + } + + this.loading = false; + this.signed = false; + } }