@@ -13,7 +13,7 @@ define(["mod_eductx/main",
13
13
"mod_eductx/contract_driver" ,
14
14
"mod_eductx/get_pdf_content" ,
15
15
"mod_eductx/connector"
16
- ] , function ( main , Buffer , Jpack , Pdfmake , Ecies , w3d , cd , pdf , Connector ) {
16
+ ] , function ( main , Buffer , Jpack , Pdfmake , Ecies , w3d , cd , pdf , Connector ) {
17
17
// Modules variables
18
18
let web3 ;
19
19
@@ -41,22 +41,22 @@ define(["mod_eductx/main",
41
41
STUDENT : "student" , AP : "ap" , AP_NO_REC : "apnorec" , NONE : "none" , NOT_IN_SYNC : "unsynced" , CERT_ISSUED : "certissued"
42
42
} ;
43
43
const ERROR = {
44
- INFO : "alert alert-info" , DANGER : "alert alert-danger" , SUCCESS : "alert alert-success" , WARNING : "alert alert-warning"
44
+ INFO : "alert alert-info" ,
45
+ DANGER : "alert alert-danger" ,
46
+ SUCCESS : "alert alert-success" ,
47
+ WARNING : "alert alert-warning"
45
48
} ;
46
49
47
50
/**
48
51
* Initializes event listeners for issue certificate button
49
52
*/
50
- const initializeEventListeners = async ( ) => {
53
+ const initializeEventListeners = async ( ) => {
51
54
document . getElementById ( "wasAwardedBy" ) . value = window . location . origin ;
52
55
if ( isAuthorized ) {
53
56
document . getElementById ( "connectFlow" ) . hidden = true ;
54
57
document . getElementById ( "issueCertificate" ) . addEventListener ( 'click' , ( ) => {
55
58
issueCredentials ( ) ;
56
59
} ) ;
57
- document . getElementById ( 'students' ) . addEventListener ( 'change' , function ( ) {
58
- document . getElementById ( "issueCertificate" ) . disabled = document . getElementById ( "students" ) . selectedOptions . length <= 0 ;
59
- } ) ;
60
60
document . getElementById ( "issueAnotherButton" ) . addEventListener ( "click" , ( ) => {
61
61
document . getElementById ( "issueAnother" ) . hidden = true ;
62
62
updateUI ( UI . AP ) ;
@@ -77,12 +77,12 @@ define(["mod_eductx/main",
77
77
}
78
78
document . getElementById ( "connectFlow" ) . hidden = false ;
79
79
// Connect Masca button
80
- document . getElementById ( "connectButton" ) . addEventListener ( 'click' , async ( ) => {
80
+ document . getElementById ( "connectButton" ) . addEventListener ( 'click' , async ( ) => {
81
81
document . getElementById ( "connectButton" ) . disabled = true ;
82
- await w3d . connectClientProvider ( async ( success ) => {
82
+ await w3d . connectClientProvider ( async ( success ) => {
83
83
if ( ! success ) {
84
- updateErrorReporting ( "Wallet not installed" , "Please consider installing" +
85
- "<a href='https://metamask.io/'>Metamask</a>." , ERROR . DANGER ) ;
84
+ updateErrorReporting ( "Wallet not installed" , "Please consider installing " +
85
+ "<a href='https://metamask.io/'>Metamask</a>." , ERROR . DANGER ) ;
86
86
document . getElementById ( "connectButton" ) . disabled = false ;
87
87
return ;
88
88
}
@@ -102,7 +102,7 @@ define(["mod_eductx/main",
102
102
} ) ;
103
103
} ;
104
104
105
- const initMasca = async ( ) => {
105
+ const initMasca = async ( ) => {
106
106
const address = await w3d . getAddressInUse ( ) ;
107
107
const enableResult = await connector . enableMasca ( address , {
108
108
snapId : "npm:@blockchain-lab-um/masca" ,
@@ -132,7 +132,7 @@ define(["mod_eductx/main",
132
132
updateCurrentAccountData ( ) ;
133
133
} ) ;
134
134
// On Provider Account Change
135
- window . ethereum . on ( "accountsChanged" , async ( accounts ) => {
135
+ window . ethereum . on ( "accountsChanged" , async ( accounts ) => {
136
136
if ( accounts . length === 0 ) {
137
137
document . getElementById ( "connectButton" ) . hidden = false ;
138
138
}
@@ -157,19 +157,24 @@ define(["mod_eductx/main",
157
157
* Prompts Metamask to confirm transaction and issue certificate to selected user
158
158
* @return {Promise<void> }
159
159
*/
160
- const issueCredentials = async ( ) => {
161
- const url = `${ endpoint } /issue-deferred/batch` ;
162
- let credentialSubjects = await buildCredentialSubjects ( ) ;
163
- const headers = {
164
- 'Content-Type' : 'application/json' ,
165
- 'schemaType' : '#educationCredentialBatch' ,
166
- "x-api-key" : apiKey
167
- } ;
160
+ const issueCredentials = async ( ) => {
161
+ const url = `${ endpoint } /api/issue-oidc` ;
162
+ let { credentialSubject, email} = await buildCredentialSubjects ( ) ;
163
+ if ( credentialSubject === null ) {
164
+ return ;
165
+ }
166
+ const headers = new Headers ( ) ;
167
+ headers . append ( 'Content-Type' , 'application/json' ) ;
168
+ headers . append ( 'schemaType' , '#educationCredential' ) ;
169
+ headers . append ( "x-api-key" , apiKey ) ;
168
170
try {
169
171
const response = await fetch ( url , {
170
172
method : 'POST' ,
171
- headers : headers ,
172
- body : JSON . stringify ( credentialSubjects ) ,
173
+ headers,
174
+ body : JSON . stringify ( {
175
+ email : email ,
176
+ data : { credentialSubject}
177
+ } ) ,
173
178
} ) ;
174
179
175
180
if ( ! response . ok ) {
@@ -186,7 +191,7 @@ define(["mod_eductx/main",
186
191
* Updates user data
187
192
* @return {Promise<void> }
188
193
*/
189
- const updateCurrentAccountData = async ( ) => {
194
+ const updateCurrentAccountData = async ( ) => {
190
195
// Validate network
191
196
if ( window . ethereum && window . ethereum . isConnected ( ) ) {
192
197
updateUI ( UI . NONE ) ;
@@ -195,7 +200,7 @@ define(["mod_eductx/main",
195
200
document . getElementById ( "connectFlow" ) . hidden = false ;
196
201
document . getElementById ( "issueFlow" ) . hidden = true ;
197
202
updateErrorReporting ( "Metamask not installed" ,
198
- "Please consider installing <a href='https://metamask.io/'>Metamask</a>" , ERROR . DANGER ) ;
203
+ "Please consider installing <a href='https://metamask.io/'> Metamask</a>" , ERROR . DANGER ) ;
199
204
return ;
200
205
}
201
206
did = ( await masca . getDID ( ) ) . data ;
@@ -222,7 +227,7 @@ define(["mod_eductx/main",
222
227
if ( did !== moodleDid && moodleDid !== null ) {
223
228
updateUI ( UI . NOT_IN_SYNC ) ;
224
229
updateErrorReporting ( "Connected DID not linked to your Moodle account" ,
225
- `Currently connected account is not linked to your Moodle account.
230
+ `Currently connected account is not linked to your Moodle account.
226
231
Please change your account in MetaMask to <b>${ moodleDid } </b>
227
232
or link the connected account.` , ERROR . WARNING ) ;
228
233
return ;
@@ -261,7 +266,7 @@ define(["mod_eductx/main",
261
266
updateErrorReporting ( "" , "" , ERROR . SUCCESS ) ;
262
267
} ;
263
268
264
- const proofOfPossession = async ( url ) => {
269
+ const proofOfPossession = async ( url ) => {
265
270
const response = await fetch ( url ) ;
266
271
const signedData = await masca . signData ( {
267
272
type : "JWT" ,
@@ -275,12 +280,12 @@ define(["mod_eductx/main",
275
280
276
281
if ( connector . isError ( signedData ) ) {
277
282
updateErrorReporting ( "Failed to sign the data" ,
278
- "There has been an error signing the proof of possession data." , ERROR . DANGER ) ;
283
+ "There has been an error signing the proof of possession data." , ERROR . DANGER ) ;
279
284
}
280
285
return signedData . data ;
281
286
} ;
282
287
283
- const getCredentialsWithPop = async ( ) => {
288
+ const getCredentialsWithPop = async ( ) => {
284
289
const url = `${ endpoint } /query` ;
285
290
const proof = await proofOfPossession ( `${ url } /nonce/${ did } ` ) ;
286
291
const claimResponse = await fetch ( `${ url } /claim` , {
@@ -296,18 +301,16 @@ define(["mod_eductx/main",
296
301
/**
297
302
* Fetches and shows current user's certificates
298
303
*/
299
- const showCredentials = async ( ) => {
304
+ const showCredentials = async ( ) => {
300
305
const vcs = await getCredentialsWithPop ( ) ;
301
306
did = ( await masca . getDID ( ) ) . data ;
302
- // eslint-disable-next-line no-console
303
- console . log ( did ) ;
304
307
if ( vcs . length === 0 ) {
305
308
document . getElementById ( "viewCertFlow" ) . innerHTML = "<h2>No credentials yet</h2>\n" ;
306
309
return ;
307
310
}
308
311
document . getElementById ( "viewCertFlow" ) . innerHTML = buildCredentialsTable ( vcs ) ;
309
312
document . querySelectorAll ( ".claim-credential" ) . forEach ( btn => {
310
- btn . addEventListener ( 'click' , async function ( ) {
313
+ btn . addEventListener ( 'click' , async function ( ) {
311
314
// eslint-disable-next-line no-console
312
315
this . disabled = true ;
313
316
const credObj = JSON . parse ( this . dataset . cred ) ;
@@ -323,7 +326,7 @@ define(["mod_eductx/main",
323
326
} ) ;
324
327
325
328
document . querySelectorAll ( ".reject-credential" ) . forEach ( btn => {
326
- btn . addEventListener ( 'click' , async function ( ) {
329
+ btn . addEventListener ( 'click' , async function ( ) {
327
330
this . disabled = true ;
328
331
const credObj = JSON . parse ( this . dataset . cred ) ;
329
332
const rejected = await requestDeletion ( credObj . id ) ;
@@ -378,9 +381,9 @@ define(["mod_eductx/main",
378
381
} else {
379
382
credentialsTable = "<h2 id='shownCertsTitle'>My Credentials</h2>" ;
380
383
credentialsTable += "<div style=\"overflow-x: scroll;\"><table class='table'>" +
381
- "<thead><th>Type</th>" +
382
- "<th>Title</th><th>Achievement</th><th>Grade</th><th>Awarding Body</th><th>ECTS</th><th></th><th></th></thead>" +
383
- "<tbody>" ;
384
+ "<thead><th>Type</th>" +
385
+ "<th>Title</th><th>Achievement</th><th>Grade</th><th>Awarding Body</th><th>ECTS</th><th></th><th></th></thead>" +
386
+ "<tbody>" ;
384
387
vcs . forEach ( ( credObj ) => {
385
388
const cred = credObj . credential ;
386
389
credentialsTable += `<tr id='${ credObj . id } '>` ;
@@ -403,7 +406,7 @@ define(["mod_eductx/main",
403
406
return credentialsTable ;
404
407
} ;
405
408
406
- const saveCredential = async ( credObj ) => {
409
+ const saveCredential = async ( credObj ) => {
407
410
const credential = credObj . credential ;
408
411
const res = await masca . saveCredential ( credential , {
409
412
store : [ 'snap' ] ,
@@ -416,7 +419,7 @@ define(["mod_eductx/main",
416
419
return true ;
417
420
} ;
418
421
419
- const requestDeletion = async ( id ) => {
422
+ const requestDeletion = async ( id ) => {
420
423
const url = `${ endpoint } /query` ;
421
424
const proof = await proofOfPossession ( `${ endpoint } /query/nonce/${ did } ` ) ;
422
425
try {
@@ -491,7 +494,7 @@ define(["mod_eductx/main",
491
494
const updateUI = ( option ) => {
492
495
if ( did ) {
493
496
document . getElementById ( "addressElement" ) . innerHTML =
494
- did . substring ( 0 , 12 ) + "..." + did . substring ( did . length - 4 , did . length ) ;
497
+ did . substring ( 0 , 12 ) + "..." + did . substring ( did . length - 4 , did . length ) ;
495
498
}
496
499
switch ( option ) {
497
500
case UI . STUDENT :
@@ -583,49 +586,46 @@ define(["mod_eductx/main",
583
586
* Return JSON object, data from input fields
584
587
* @return {Promise<{obj}> }
585
588
*/
586
- const buildCredentialSubjects = async ( ) => {
589
+ const buildCredentialSubjects = async ( ) => {
587
590
let dropDown = document . getElementById ( 'students' ) ;
588
- const selectedValues = [ ] ;
589
- for ( let i = 0 ; i < dropDown . options . length ; i ++ ) {
590
- if ( dropDown . options [ i ] . selected ) {
591
- const value = JSON . parse ( dropDown . options [ i ] . value ) ;
592
- selectedValues . push ( {
593
- credentialSubject : {
594
- currentFamilyName : value . lastName ,
595
- currentGivenName : value . firstName ,
596
- id : value . did ,
597
- dateOfBirth : null ,
598
- personIdentifier : null ,
599
- achieved : {
591
+ if ( dropDown . value ) {
592
+ const value = JSON . parse ( dropDown . value ) ;
593
+ return {
594
+ credentialSubject : {
595
+ currentFamilyName : value . lastName ,
596
+ currentGivenName : value . firstName ,
597
+ id : value . did || null ,
598
+ dateOfBirth : null ,
599
+ personIdentifier : null ,
600
+ achieved : {
601
+ id : null ,
602
+ title : document . getElementById ( "achievement" ) . value || null ,
603
+ specifiedBy : {
600
604
id : null ,
601
- title : document . getElementById ( "achievement" ) . value ,
602
- specifiedBy : {
603
- id : null ,
604
- title : "Example" , // Course iz moodla ime
605
- volumeOfLearning : null ,
606
- iSCEDFCode : null ,
607
- eCTSCreditPoints : document . getElementById ( "ects" ) . value
608
- } ,
609
- wasAwardedBy : {
610
- id : document . getElementById ( "wasAwardedBy" ) . value ,
611
- awardingBody : null ,
612
- awardingBodyDescription : document . getElementById ( "awardingBodyDescription" ) . value ,
613
- awardingDate : null ,
614
- awardingLocation : null
615
- } ,
616
- wasDerivedFrom : {
617
- id : null ,
618
- title : document . getElementById ( "title" ) . value ,
619
- grade : document . getElementById ( "grade" ) . value ,
620
- issuedDate : Date . now ( ) . toString ( )
621
- } ,
622
- associatedLearningOpportunity : null
623
- }
605
+ title : "Example" , // Course iz moodla ime
606
+ volumeOfLearning : null ,
607
+ iSCEDFCode : null ,
608
+ eCTSCreditPoints : document . getElementById ( "ects" ) . value
609
+ } ,
610
+ wasAwardedBy : {
611
+ id : document . getElementById ( "wasAwardedBy" ) . value ,
612
+ awardingBody : null ,
613
+ awardingBodyDescription : document . getElementById ( "awardingBodyDescription" ) . value ,
614
+ awardingDate : null ,
615
+ awardingLocation : null
616
+ } ,
617
+ wasDerivedFrom : {
618
+ id : null ,
619
+ title : document . getElementById ( "title" ) . value ,
620
+ grade : document . getElementById ( "grade" ) . value ,
621
+ issuedDate : Date . now ( ) . toString ( )
622
+ } ,
623
+ associatedLearningOpportunity : null
624
624
}
625
- } ) ;
626
- }
625
+ } , email : value . email
626
+ } ;
627
627
}
628
- return selectedValues ;
628
+ return { credentialSubject : null , email : null } ;
629
629
} ;
630
630
631
631
/**
0 commit comments