diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-21 08:30:39 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-21 08:30:39 +0300 |
commit | 911a56b56c4f9ec5d0c4f1fd15189102bc97fcdb (patch) | |
tree | d8a6cb36c6a7cacad9cd1b8c94755f3f974084e4 /src/ui | |
parent | 548034e167bd94d21ef9bcc2e6d2d8cbfaeb3d06 (diff) |
Added identity exporting
Exporting an identity will display it in a new tab in PEM encoded format, where it can be saved or copied.
IssueID #236
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/documentwidget.c | 81 | ||||
-rw-r--r-- | src/ui/documentwidget.h | 1 | ||||
-rw-r--r-- | src/ui/root.c | 5 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 32 |
4 files changed, 78 insertions, 41 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 452e5508..337e2a03 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -976,7 +976,7 @@ iBool isPinned_DocumentWidget_(const iDocumentWidget *d) { | |||
976 | 976 | ||
977 | static void showOrHidePinningIndicator_DocumentWidget_(iDocumentWidget *d) { | 977 | static void showOrHidePinningIndicator_DocumentWidget_(iDocumentWidget *d) { |
978 | iWidget *w = as_Widget(d); | 978 | iWidget *w = as_Widget(d); |
979 | showCollapsed_Widget(findChild_Widget(root_Widget(as_Widget(d)), "document.pinned"), | 979 | showCollapsed_Widget(findChild_Widget(root_Widget(w), "document.pinned"), |
980 | isPinned_DocumentWidget_(d)); | 980 | isPinned_DocumentWidget_(d)); |
981 | } | 981 | } |
982 | 982 | ||
@@ -1214,7 +1214,9 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
1214 | setRange_String(&d->sourceMime, param); | 1214 | setRange_String(&d->sourceMime, param); |
1215 | } | 1215 | } |
1216 | else if (startsWith_Rangecc(param, "text/") || | 1216 | else if (startsWith_Rangecc(param, "text/") || |
1217 | equal_Rangecc(param, "application/json")) { | 1217 | equal_Rangecc(param, "application/json") || |
1218 | equal_Rangecc(param, "application/x-pem-file") || | ||
1219 | equal_Rangecc(param, "application/pem-certificate-chain")) { | ||
1218 | docFormat = plainText_GmDocumentFormat; | 1220 | docFormat = plainText_GmDocumentFormat; |
1219 | setRange_String(&d->sourceMime, param); | 1221 | setRange_String(&d->sourceMime, param); |
1220 | } | 1222 | } |
@@ -1383,37 +1385,42 @@ static void cacheDocumentGlyphs_DocumentWidget_(const iDocumentWidget *d) { | |||
1383 | } | 1385 | } |
1384 | } | 1386 | } |
1385 | 1387 | ||
1388 | static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float normScrollY, | ||
1389 | const iGmResponse *resp) { | ||
1390 | setLinkNumberMode_DocumentWidget_(d, iFalse); | ||
1391 | clear_ObjectList(d->media); | ||
1392 | delete_Gempub(d->sourceGempub); | ||
1393 | d->sourceGempub = NULL; | ||
1394 | reset_GmDocument(d->doc); | ||
1395 | resetWideRuns_DocumentWidget_(d); | ||
1396 | d->state = fetching_RequestState; | ||
1397 | /* Do the fetch. */ { | ||
1398 | d->initNormScrollY = normScrollY; | ||
1399 | /* Use the cached response data. */ | ||
1400 | updateTrust_DocumentWidget_(d, resp); | ||
1401 | d->sourceTime = resp->when; | ||
1402 | d->sourceStatus = success_GmStatusCode; | ||
1403 | format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached")); | ||
1404 | set_Block(&d->sourceContent, &resp->body); | ||
1405 | updateDocument_DocumentWidget_(d, resp, iTrue); | ||
1406 | postProcessRequestContent_DocumentWidget_(d, iTrue); | ||
1407 | } | ||
1408 | d->state = ready_RequestState; | ||
1409 | init_Anim(&d->altTextOpacity, 0); | ||
1410 | reset_SmoothScroll(&d->scrollY); | ||
1411 | init_Anim(&d->scrollY.pos, d->initNormScrollY * size_GmDocument(d->doc).y); | ||
1412 | updateSideOpacity_DocumentWidget_(d, iFalse); | ||
1413 | updateVisible_DocumentWidget_(d); | ||
1414 | moveSpan_SmoothScroll(&d->scrollY, 0, 0); /* clamp position to new max */ | ||
1415 | cacheDocumentGlyphs_DocumentWidget_(d); | ||
1416 | d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag; | ||
1417 | postCommandf_Root(as_Widget(d)->root, "document.changed doc:%p url:%s", d, cstr_String(d->mod.url)); | ||
1418 | } | ||
1419 | |||
1386 | static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { | 1420 | static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { |
1387 | const iRecentUrl *recent = findUrl_History(d->mod.history, d->mod.url); | 1421 | const iRecentUrl *recent = findUrl_History(d->mod.history, d->mod.url); |
1388 | if (recent && recent->cachedResponse) { | 1422 | if (recent && recent->cachedResponse) { |
1389 | const iGmResponse *resp = recent->cachedResponse; | 1423 | updateFromCachedResponse_DocumentWidget_(d, recent->normScrollY, recent->cachedResponse); |
1390 | clear_ObjectList(d->media); | ||
1391 | delete_Gempub(d->sourceGempub); | ||
1392 | d->sourceGempub = NULL; | ||
1393 | reset_GmDocument(d->doc); | ||
1394 | resetWideRuns_DocumentWidget_(d); | ||
1395 | d->state = fetching_RequestState; | ||
1396 | /* Do the fetch. */ { | ||
1397 | d->initNormScrollY = recent->normScrollY; | ||
1398 | /* Use the cached response data. */ | ||
1399 | updateTrust_DocumentWidget_(d, resp); | ||
1400 | d->sourceTime = resp->when; | ||
1401 | d->sourceStatus = success_GmStatusCode; | ||
1402 | format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached")); | ||
1403 | set_Block(&d->sourceContent, &resp->body); | ||
1404 | updateDocument_DocumentWidget_(d, resp, iTrue); | ||
1405 | postProcessRequestContent_DocumentWidget_(d, iTrue); | ||
1406 | } | ||
1407 | d->state = ready_RequestState; | ||
1408 | init_Anim(&d->altTextOpacity, 0); | ||
1409 | reset_SmoothScroll(&d->scrollY); | ||
1410 | init_Anim(&d->scrollY.pos, d->initNormScrollY * size_GmDocument(d->doc).y); | ||
1411 | updateSideOpacity_DocumentWidget_(d, iFalse); | ||
1412 | updateVisible_DocumentWidget_(d); | ||
1413 | moveSpan_SmoothScroll(&d->scrollY, 0, 0); /* clamp position to new max */ | ||
1414 | cacheDocumentGlyphs_DocumentWidget_(d); | ||
1415 | d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag; | ||
1416 | postCommandf_Root(as_Widget(d)->root, "document.changed doc:%p url:%s", d, cstr_String(d->mod.url)); | ||
1417 | return iTrue; | 1424 | return iTrue; |
1418 | } | 1425 | } |
1419 | else if (!isEmpty_String(d->mod.url)) { | 1426 | else if (!isEmpty_String(d->mod.url)) { |
@@ -4413,6 +4420,20 @@ void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBoo | |||
4413 | } | 4420 | } |
4414 | } | 4421 | } |
4415 | 4422 | ||
4423 | void setUrlAndSource_DocumentWidget(iDocumentWidget *d, const iString *url, const iString *mime, | ||
4424 | const iBlock *source) { | ||
4425 | setLinkNumberMode_DocumentWidget_(d, iFalse); | ||
4426 | set_String(d->mod.url, url); | ||
4427 | parseUser_DocumentWidget_(d); | ||
4428 | iGmResponse *resp = new_GmResponse(); | ||
4429 | resp->statusCode = success_GmStatusCode; | ||
4430 | initCurrent_Time(&resp->when); | ||
4431 | set_String(&resp->meta, mime); | ||
4432 | set_Block(&resp->body, source); | ||
4433 | updateFromCachedResponse_DocumentWidget_(d, 0, resp); | ||
4434 | delete_GmResponse(resp); | ||
4435 | } | ||
4436 | |||
4416 | iDocumentWidget *duplicate_DocumentWidget(const iDocumentWidget *orig) { | 4437 | iDocumentWidget *duplicate_DocumentWidget(const iDocumentWidget *orig) { |
4417 | iDocumentWidget *d = new_DocumentWidget(); | 4438 | iDocumentWidget *d = new_DocumentWidget(); |
4418 | delete_History(d->mod.history); | 4439 | delete_History(d->mod.history); |
diff --git a/src/ui/documentwidget.h b/src/ui/documentwidget.h index 12603437..c038f981 100644 --- a/src/ui/documentwidget.h +++ b/src/ui/documentwidget.h | |||
@@ -47,6 +47,7 @@ int documentWidth_DocumentWidget (const iDocumentWidget *); | |||
47 | 47 | ||
48 | void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); | 48 | void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); |
49 | void setUrlFromCache_DocumentWidget (iDocumentWidget *, const iString *url, iBool isFromCache); | 49 | void setUrlFromCache_DocumentWidget (iDocumentWidget *, const iString *url, iBool isFromCache); |
50 | void setUrlAndSource_DocumentWidget (iDocumentWidget *, const iString *url, const iString *mime, const iBlock *source); | ||
50 | void setInitialScroll_DocumentWidget (iDocumentWidget *, float normScrollY); /* set after content received */ | 51 | void setInitialScroll_DocumentWidget (iDocumentWidget *, float normScrollY); /* set after content received */ |
51 | void setRedirectCount_DocumentWidget (iDocumentWidget *, int count); | 52 | void setRedirectCount_DocumentWidget (iDocumentWidget *, int count); |
52 | void setSource_DocumentWidget (iDocumentWidget *, const iString *sourceText); | 53 | void setSource_DocumentWidget (iDocumentWidget *, const iString *sourceText); |
diff --git a/src/ui/root.c b/src/ui/root.c index 1698a5d4..9a089992 100644 --- a/src/ui/root.c +++ b/src/ui/root.c | |||
@@ -438,10 +438,7 @@ static void updateNavBarIdentity_(iWidget *navBar) { | |||
438 | setFlags_Widget(tool, selected_WidgetFlag, ident != NULL); | 438 | setFlags_Widget(tool, selected_WidgetFlag, ident != NULL); |
439 | /* Update menu. */ | 439 | /* Update menu. */ |
440 | iLabelWidget *idItem = child_Widget(findChild_Widget(button, "menu"), 0); | 440 | iLabelWidget *idItem = child_Widget(findChild_Widget(button, "menu"), 0); |
441 | iString *subjectName = ident ? collect_String(subject_TlsCertificate(ident->cert)) : NULL; | 441 | const iString *subjectName = ident ? name_GmIdentity(ident) : NULL; |
442 | if (subjectName && startsWith_String(subjectName, "CN = ")) { | ||
443 | remove_Block(&subjectName->chars, 0, 5); | ||
444 | } | ||
445 | setTextCStr_LabelWidget( | 442 | setTextCStr_LabelWidget( |
446 | idItem, | 443 | idItem, |
447 | subjectName ? format_CStr(uiTextAction_ColorEscape "%s", cstr_String(subjectName)) | 444 | subjectName ? format_CStr(uiTextAction_ColorEscape "%s", cstr_String(subjectName)) |
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index 556ae951..f9bdbf67 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -169,9 +169,10 @@ static void updateContextMenu_SidebarWidget_(iSidebarWidget *d) { | |||
169 | { "---", 0, 0, NULL }, | 169 | { "---", 0, 0, NULL }, |
170 | { edit_Icon " ${menu.edit.notes}", 0, 0, "ident.edit" }, | 170 | { edit_Icon " ${menu.edit.notes}", 0, 0, "ident.edit" }, |
171 | { "${ident.fingerprint}", 0, 0, "ident.fingerprint" }, | 171 | { "${ident.fingerprint}", 0, 0, "ident.fingerprint" }, |
172 | { export_Icon " ${ident.export}", 0, 0, "ident.export" }, | ||
172 | { "---", 0, 0, NULL }, | 173 | { "---", 0, 0, NULL }, |
173 | { delete_Icon " " uiTextCaution_ColorEscape "${ident.delete}", 0, 0, "ident.delete confirm:1" }, | 174 | { delete_Icon " " uiTextCaution_ColorEscape "${ident.delete}", 0, 0, "ident.delete confirm:1" }, |
174 | }, 8); | 175 | }, 9); |
175 | /* Used URLs. */ | 176 | /* Used URLs. */ |
176 | const iGmIdentity *ident = menuIdentity_SidebarWidget_(d); | 177 | const iGmIdentity *ident = menuIdentity_SidebarWidget_(d); |
177 | if (ident) { | 178 | if (ident) { |
@@ -440,10 +441,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
440 | iSidebarItem *item = new_SidebarItem(); | 441 | iSidebarItem *item = new_SidebarItem(); |
441 | item->id = (uint32_t) index_PtrArrayConstIterator(&i); | 442 | item->id = (uint32_t) index_PtrArrayConstIterator(&i); |
442 | item->icon = 0x1f464; /* person */ | 443 | item->icon = 0x1f464; /* person */ |
443 | set_String(&item->label, collect_String(subject_TlsCertificate(ident->cert))); | 444 | set_String(&item->label, name_GmIdentity(ident)); |
444 | if (startsWith_String(&item->label, "CN = ")) { | ||
445 | remove_Block(&item->label.chars, 0, 5); | ||
446 | } | ||
447 | iDate until; | 445 | iDate until; |
448 | validUntil_TlsCertificate(ident->cert, &until); | 446 | validUntil_TlsCertificate(ident->cert, &until); |
449 | const iBool isActive = isUsedOn_GmIdentity(ident, tabUrl); | 447 | const iBool isActive = isUsedOn_GmIdentity(ident, tabUrl); |
@@ -480,11 +478,11 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
480 | addActionButton_SidebarWidget_(d, add_Icon " ${sidebar.action.ident.new}", "ident.new", 0); | 478 | addActionButton_SidebarWidget_(d, add_Icon " ${sidebar.action.ident.new}", "ident.new", 0); |
481 | addActionButton_SidebarWidget_(d, "${sidebar.action.ident.import}", "ident.import", 0); | 479 | addActionButton_SidebarWidget_(d, "${sidebar.action.ident.import}", "ident.import", 0); |
482 | } | 480 | } |
481 | /* | ||
483 | const iMenuItem menuItems[] = { | 482 | const iMenuItem menuItems[] = { |
484 | { person_Icon " ${ident.use}", 0, 0, "ident.use arg:1" }, | 483 | { person_Icon " ${ident.use}", 0, 0, "ident.use arg:1" }, |
485 | { close_Icon " ${ident.stopuse}", 0, 0, "ident.use arg:0" }, | 484 | { close_Icon " ${ident.stopuse}", 0, 0, "ident.use arg:0" }, |
486 | { close_Icon " ${ident.stopuse.all}", 0, 0, "ident.use arg:0 clear:1" }, | 485 | { close_Icon " ${ident.stopuse.all}", 0, 0, "ident.use arg:0 clear:1" }, |
487 | { "${ident.showuse}", 0, 0, "ident.showuse" }, | ||
488 | { "---", 0, 0, NULL }, | 486 | { "---", 0, 0, NULL }, |
489 | { edit_Icon " ${menu.edit.notes}", 0, 0, "ident.edit" }, | 487 | { edit_Icon " ${menu.edit.notes}", 0, 0, "ident.edit" }, |
490 | { "${ident.fingerprint}", 0, 0, "ident.fingerprint" }, | 488 | { "${ident.fingerprint}", 0, 0, "ident.fingerprint" }, |
@@ -494,6 +492,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
494 | { delete_Icon " " uiTextCaution_ColorEscape "${ident.delete}", 0, 0, "ident.delete confirm:1" }, | 492 | { delete_Icon " " uiTextCaution_ColorEscape "${ident.delete}", 0, 0, "ident.delete confirm:1" }, |
495 | }; | 493 | }; |
496 | d->menu = makeMenu_Widget(as_Widget(d), menuItems, iElemCount(menuItems)); | 494 | d->menu = makeMenu_Widget(as_Widget(d), menuItems, iElemCount(menuItems)); |
495 | */ | ||
497 | break; | 496 | break; |
498 | } | 497 | } |
499 | default: | 498 | default: |
@@ -792,6 +791,9 @@ static void itemClicked_SidebarWidget_(iSidebarWidget *d, iSidebarItem *item, si | |||
792 | } | 791 | } |
793 | case identities_SidebarMode: { | 792 | case identities_SidebarMode: { |
794 | d->contextItem = item; | 793 | d->contextItem = item; |
794 | if (d->contextIndex != iInvalidPos) { | ||
795 | invalidateItem_ListWidget(d->list, d->contextIndex); | ||
796 | } | ||
795 | d->contextIndex = itemIndex; | 797 | d->contextIndex = itemIndex; |
796 | if (itemIndex < numItems_ListWidget(d->list)) { | 798 | if (itemIndex < numItems_ListWidget(d->list)) { |
797 | updateContextMenu_SidebarWidget_(d); | 799 | updateContextMenu_SidebarWidget_(d); |
@@ -1277,6 +1279,20 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1277 | } | 1279 | } |
1278 | return iTrue; | 1280 | return iTrue; |
1279 | } | 1281 | } |
1282 | else if (isCommand_Widget(w, ev, "ident.export")) { | ||
1283 | const iGmIdentity *ident = menuIdentity_SidebarWidget_(d); | ||
1284 | if (ident) { | ||
1285 | iString *pem = collect_String(pem_TlsCertificate(ident->cert)); | ||
1286 | append_String(pem, collect_String(privateKeyPem_TlsCertificate(ident->cert))); | ||
1287 | iDocumentWidget *expTab = newTab_App(NULL, iTrue); | ||
1288 | setUrlAndSource_DocumentWidget( | ||
1289 | expTab, | ||
1290 | collectNewFormat_String("file:%s.pem", cstr_String(name_GmIdentity(ident))), | ||
1291 | collectNewCStr_String("text/plain"), | ||
1292 | utf8_String(pem)); | ||
1293 | } | ||
1294 | return iTrue; | ||
1295 | } | ||
1280 | else if (isCommand_Widget(w, ev, "ident.setnotes")) { | 1296 | else if (isCommand_Widget(w, ev, "ident.setnotes")) { |
1281 | iGmIdentity *ident = pointerLabel_Command(cmd, "ident"); | 1297 | iGmIdentity *ident = pointerLabel_Command(cmd, "ident"); |
1282 | if (ident) { | 1298 | if (ident) { |
@@ -1385,7 +1401,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1385 | d->contextIndex = iInvalidPos; | 1401 | d->contextIndex = iInvalidPos; |
1386 | } | 1402 | } |
1387 | } | 1403 | } |
1388 | if (d->menu && ev->type == SDL_MOUSEBUTTONDOWN) { | 1404 | if ((d->menu || d->mode == identities_SidebarMode )&& ev->type == SDL_MOUSEBUTTONDOWN) { |
1389 | if (ev->button.button == SDL_BUTTON_RIGHT) { | 1405 | if (ev->button.button == SDL_BUTTON_RIGHT) { |
1390 | d->contextItem = NULL; | 1406 | d->contextItem = NULL; |
1391 | if (!isVisible_Widget(d->menu)) { | 1407 | if (!isVisible_Widget(d->menu)) { |
@@ -1457,11 +1473,13 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1457 | (!cmdClear && cmdUse && isUsedOn_GmIdentity(ident, docUrl)) || | 1473 | (!cmdClear && cmdUse && isUsedOn_GmIdentity(ident, docUrl)) || |
1458 | (!cmdClear && !cmdUse && !isUsedOn_GmIdentity(ident, docUrl))); | 1474 | (!cmdClear && !cmdUse && !isUsedOn_GmIdentity(ident, docUrl))); |
1459 | } | 1475 | } |
1476 | /* | ||
1460 | else if (equal_Command(cmdItem, "ident.showuse")) { | 1477 | else if (equal_Command(cmdItem, "ident.showuse")) { |
1461 | setFlags_Widget(as_Widget(menuItem), | 1478 | setFlags_Widget(as_Widget(menuItem), |
1462 | disabled_WidgetFlag, | 1479 | disabled_WidgetFlag, |
1463 | !isUsed_GmIdentity(ident)); | 1480 | !isUsed_GmIdentity(ident)); |
1464 | } | 1481 | } |
1482 | */ | ||
1465 | } | 1483 | } |
1466 | } | 1484 | } |
1467 | } | 1485 | } |