[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[reclaim-ui] 368/459: settings page, experiments tweaks
From: |
gnunet |
Subject: |
[reclaim-ui] 368/459: settings page, experiments tweaks |
Date: |
Fri, 11 Jun 2021 23:27:40 +0200 |
This is an automated email from the git hooks/post-receive script.
martin-schanzenbach pushed a commit to branch master
in repository reclaim-ui.
commit 06b05b006ed7d22a69282d5dfae80c420e122b53
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Thu Dec 24 13:24:50 2020 +0900
settings page, experiments tweaks
---
src/app/app-routing.module.ts | 6 +-
src/app/app.component.html | 6 +-
src/app/app.component.ts | 7 -
src/app/app.module.ts | 6 +-
src/app/config.service.ts | 30 ++-
src/app/config/config.component.html | 6 +
src/app/config/config.component.ts | 18 +-
.../edit-credentials.component.html | 26 +--
.../edit-credentials/edit-credentials.component.ts | 222 ---------------------
src/app/edit-identity/edit-identity.component.html | 9 +
src/app/edit-identity/edit-identity.component.ts | 4 +
src/app/identity-list/identity-list.component.ts | 6 +-
.../import-attributes.component.ts | 13 +-
src/locales/en/messages.json | 14 +-
14 files changed, 91 insertions(+), 282 deletions(-)
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 7c221b0..1ea7895 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -5,7 +5,9 @@ import { NewIdentityComponent } from
'./new-identity/new-identity.component';
import { EditIdentityComponent } from
'./edit-identity/edit-identity.component';
import { EditAuthorizationsComponent } from
'./edit-authorizations/edit-authorizations.component';
import { EditCredentialsComponent } from
'./edit-credentials/edit-credentials.component';
+import { ImportAttributesComponent } from
'./import-attributes/import-attributes.component';
import { AuthorizationRequestComponent } from
'./authorization-request/authorization-request.component';
+import { ConfigComponent } from './config/config.component';
const routes: Routes = [
{ path: 'index.html', component: IdentityListComponent },
@@ -15,7 +17,9 @@ const routes: Routes = [
{ path: 'edit-identity/:id', component: EditIdentityComponent },
{ path: 'edit-authorizations/:id', component: EditAuthorizationsComponent
},
{ path: 'edit-credentials/:id', component: EditCredentialsComponent },
- { path: 'authorization-request', component: AuthorizationRequestComponent }
+ { path: 'import-attributes/:id', component: ImportAttributesComponent },
+ { path: 'authorization-request', component: AuthorizationRequestComponent
},
+ { path: 'config', component: ConfigComponent }
];
@NgModule({
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 7bb4ac3..3877791 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,6 +1,2 @@
-<div class="logo"><img src="assets/reclaim_icon.png"/></div>
+<div class="logo"><img src="assets/reclaim_icon.png"/><button class="btn
btn-primary" [routerLink]="['/config']" style="float:right;"><i class="fa
fa-cog"></i></button></div>
<router-outlet></router-outlet>
-<div style="margin: 1em" (click)="toggleExperimental()">
- <i [className]="isExperimental() ? 'fa fa-toggle-on' : 'fa
fa-toggle-off'"></i>
- <b
*ngIf="isExperimental()">{{getMessage("app_html@experimentalEnabled")}}</b><span
*ngIf="!isExperimental()">{{getMessage("app_html@experimentalDisabled")}}</span>
-</div>
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index b93cafd..f233feb 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -20,13 +20,6 @@ export class AppComponent {
this.configService = _configService;
}
- isExperimental() {
- return this.configService.get().experiments;
- }
-
- toggleExperimental() {
- this.configService.get().experiments =
!this.configService.get().experiments;
- }
//Internationalization
getMessage(key, sub?){
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 1bfb1d9..dd3d06d 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -23,6 +23,8 @@ import { AuthorizationRequestComponent } from
'./authorization-request/authoriza
import { EditAuthorizationsComponent } from
'./edit-authorizations/edit-authorizations.component';
import { EditCredentialsComponent } from
'./edit-credentials/edit-credentials.component';
import { OAuthStorage } from 'angular-oauth2-oidc';
+import { ImportAttributesComponent } from
'./import-attributes/import-attributes.component';
+import { ConfigComponent } from './config/config.component';
@NgModule({
declarations: [
@@ -34,7 +36,9 @@ import { OAuthStorage } from 'angular-oauth2-oidc';
EditIdentityComponent,
AuthorizationRequestComponent,
EditAuthorizationsComponent,
- EditCredentialsComponent
+ EditCredentialsComponent,
+ ImportAttributesComponent,
+ ConfigComponent
],
imports: [
BrowserModule,
diff --git a/src/app/config.service.ts b/src/app/config.service.ts
index c0eefd0..03dabdb 100644
--- a/src/app/config.service.ts
+++ b/src/app/config.service.ts
@@ -6,14 +6,38 @@ import { Config } from './config';
@Injectable()
export class ConfigService {
config: Config;
+ defaultConfig: Config;
- constructor(private http: HttpClient) { }
+ constructor(private http: HttpClient) {
+ var confString = localStorage.getItem('reclaimSettings');
+ try {
+ this.config = JSON.parse(confString);
+ console.log("Loaded settings: " + confString);
+ } catch(e) {
+ this.http.get<Config>('assets/config.json').subscribe(cnf => {
+ this.config = cnf;
+ console.log("Got default settings: " + cnf);
+ });
+ console.log("Error loading settings: " + e);
+ }
+ }
- get() {
+ get(): Config {
return this.config;
}
+ save(cnf: Config) {
+ try {
+ var confString = JSON.stringify(cnf);
+ localStorage.setItem('reclaimSettings', confString);
+ this.config = cnf;
+ console.log("Saved: " + confString);
+ } catch(e) {
+ console.log(confString);
+ }
+ }
+
async load() {
- this.config = await
this.http.get<Config>('assets/config.json').toPromise();
+ this.defaultConfig = await
this.http.get<Config>('assets/config.json').toPromise();
}
}
diff --git a/src/app/config/config.component.html
b/src/app/config/config.component.html
index d5f4c6c..69a94c6 100644
--- a/src/app/config/config.component.html
+++ b/src/app/config/config.component.html
@@ -10,6 +10,12 @@
<i [className]="isExperimental() ? 'fa fa-toggle-on mr-2' : 'fa
fa-toggle-off mr-2'"></i>
<b
*ngIf="isExperimental()">{{getMessage("app_html@experimentalEnabled")}}</b><span
*ngIf="!isExperimental()">{{getMessage("app_html@experimentalDisabled")}}</span>
</div>
+ <span class="mr-2">re:claimID REST API base URL</span> <input
[(ngModel)]="config.apiUrl">
+ <div>
+ <button class="btn btn-primary" (click)="saveAndBack()">
+ <span class="fa fa-save"></span> {{ getMessage("SaveAndBack") }}
+ </button>
+
</div>
</div>
diff --git a/src/app/config/config.component.ts
b/src/app/config/config.component.ts
index 52e9af9..b68eddd 100644
--- a/src/app/config/config.component.ts
+++ b/src/app/config/config.component.ts
@@ -1,7 +1,8 @@
import { Component, OnInit } from '@angular/core';
import { ConfigService } from '../config.service';
+import { Config } from '../config';
import { LanguageService } from '../language.service';
-
+import { ActivatedRoute, Router} from '@angular/router';
@Component({
selector: 'app-config',
@@ -11,14 +12,17 @@ import { LanguageService } from '../language.service';
export class ConfigComponent implements OnInit {
configService: ConfigService;
+ config: Config;
constructor(private _configService: ConfigService,
- private languageService: LanguageService) {
+ private languageService: LanguageService,
+ private router: Router) {
this.configService = _configService;
}
ngOnInit(): void {
+ this.config = this.configService.get();
}
isExperimental() {
@@ -26,10 +30,12 @@ export class ConfigComponent implements OnInit {
}
toggleExperimental() {
- var config = this.configService.get();
- console.log("Config is: "+config);
- config.experiments = !config.experiments;
- this.configService.save(config);
+ this.config.experiments = !this.config.experiments;
+ }
+
+ saveAndBack() {
+ this.configService.save(this.config);
+ this.router.navigate(['/']);
}
//Internationalization
diff --git a/src/app/edit-credentials/edit-credentials.component.html
b/src/app/edit-credentials/edit-credentials.component.html
index dc2bea2..d9b0e58 100644
--- a/src/app/edit-credentials/edit-credentials.component.html
+++ b/src/app/edit-credentials/edit-credentials.component.html
@@ -103,35 +103,13 @@
class="fa fa-times"></span> </div>
</td>
</tr>
- <tr [class.alert-danger]="isCredInConflict(newCredential)"
*ngIf="loggedIn()">
- <td>
- <input [class.text-danger]="!credentialNameValid(newCredential)"
placeholder="{{getMessage('edit_credentials_html@credentials')}}"
- [(ngModel)]="newCredential.name">
- </td>
- <td>
- <div style="min-width: 15em">JWT</div>
- </td>
- <td>
- {{getNewCredentialExpiration()}}
- </td>
- <td>
- <div style="min-width: 15em">{{newIdProvider.url}}</div>
- </td>
- <td>
- <button class="btn btn-primary"
[disabled]="!canAddCredential(newCredential)" (click)="saveIdProvider()">
- <span class="fa fa-plus"></span>
- </button>
- <button class="btn btn-primary ml-2" (click)="cancelAdding()">
- <span class="fa fa-trash"></span>
- </button>
- </td>
- </tr>
+ <!-- FIXME implement adding plain text credentials -->
</tbody>
</table>
<!-- Edit card buttons -->
<div>
- <button class="btn btn-primary" (click)="goBack()"
[disabled]="!canGoBack()">
+ <button class="btn btn-primary" [routerLink]="['/edit-identity',
identity.name ]">
<span class="fa fa-save"></span> {{getMessage("Back")}}
</button>
</div>
diff --git a/src/app/edit-credentials/edit-credentials.component.ts
b/src/app/edit-credentials/edit-credentials.component.ts
index c19a0f9..1ac2acf 100644
--- a/src/app/edit-credentials/edit-credentials.component.ts
+++ b/src/app/edit-credentials/edit-credentials.component.ts
@@ -23,11 +23,6 @@ export class EditCredentialsComponent implements OnInit {
identity: Identity;
credentials: Credential[];
newCredential: Credential;
- newIdProvider: IdProvider;
- webfingerEmail: string;
- emailNotFoundAlertClosed: boolean;
- errorMassage: string;
- scopes: Scope[];
constructor(private reclaimService: ReclaimService,
private identityService: IdentityService,
@@ -40,26 +35,7 @@ export class EditCredentialsComponent implements OnInit {
ngOnInit() {
this.newCredential = new Credential('', '', '', 'JWT', '', 0, []);
this.identity = new Identity('','');
- this.newIdProvider = new IdProvider ('', '');
- this.webfingerEmail = '';
- this.emailNotFoundAlertClosed = true;
- this.errorMassage = '';
- this.loadScopesFromLocalStorage()
- this.loadIdProviderFromLocalStorage();
this.credentials = [];
- if (this.newIdProvider.url !== ''){
- const loginOptions: LoginOptions = {
- customHashFragment: "?code="+localStorage.getItem("credentialCode") +
"&state=" + localStorage.getItem("credentialState") + "&session_state="+
localStorage.getItem("credentialSession_State"),
- }
- this.configureOauthService();
- if (!localStorage.getItem("credentialCode")){
- this.oauthService.loadDiscoveryDocumentAndTryLogin();
- }
- else{
- this.oauthService.loadDiscoveryDocumentAndTryLogin(loginOptions);
- }
-
- }
this.activatedRoute.params.subscribe(p => {
if (p['id'] === undefined) {
return;
@@ -86,60 +62,6 @@ export class EditCredentialsComponent implements OnInit {
});
}
- saveIdProvider(){
- this.saveIdProviderinLocalStorage();
- this.addCredential();
- }
-
- addCredential() {
- if (!this.oauthService.hasValidAccessToken()){
- console.log("No AccessToken");
- return;
- }
- this.newCredential.value = this.oauthService.getIdToken();
- this.reclaimService.addCredential(this.identity,
this.newCredential).subscribe(res => {
- console.log("Saved Credential");
- this.resetNewIdProvider();
- this.resetScopes();
- this.updateCredentials();
- this.newCredential.name = '';
- this.newCredential.value = '';
- this.logOutFromOauthService();
- },
- err => {
- console.log("Failed saving credential");
- console.log(err);
- //this.errorInfos.push("Failed to update identity ``" +
this.identityInEdit.name + "''");
- EMPTY
- this.newCredential.name = '';
- this.newCredential.value = '';
- this.logOutFromOauthService();
- });
- }
-
- saveIdProviderinLocalStorage(){
- localStorage.setItem('Authorization: ' + this.newCredential.name,
'idProvider: ' + this.newIdProvider.url + ';redirectUri: ' +
this.oauthService.redirectUri + ';clientId: ' + this.oauthService.clientId +
';accessToken: ' + this.oauthService.getIdToken() + ';idToken: ' +
this.oauthService.getIdToken());
- }
-
- private storeCredential() {
- const promises = [];
- if ((this.newCredential.value !== '') || (this.newCredential.type !== ''))
{
- promises.push(from(this.reclaimService.addCredential(this.identity,
this.newCredential)));
- }
- return forkJoin(promises);
- }
-
- canGoBack() {
- if (this.newIdProvider.url === ''){
- return true;
- }
- return false;
- }
-
- goBack() {
- this.router.navigate(['/edit-identity', this.identity.name]);
- }
-
isCredInConflict(credential: Credential) {
let i;
if (undefined !== this.credentials) {
@@ -213,150 +135,6 @@ export class EditCredentialsComponent implements OnInit {
return true;
}
- loadIdProviderFromLocalStorage(){
- this.newIdProvider.url = localStorage.getItem("newIdProviderURL") || '';
- this.newIdProvider.name =
this.getNewIdProviderName(this.newIdProvider.url);
- }
-
- getNewIdProviderName(url: string){
- return url.split('//')[1];
- }
-
- getNewCredentialExpiration(){
- var exp = new Date(0);
- exp.setMilliseconds(this.oauthService.getIdTokenExpiration());
- return exp.toLocaleString();
- }
-
- resetNewIdProvider(){
- this.newIdProvider.url = '';
- this.newIdProvider.name = '';
- localStorage.removeItem('newIdProviderURL');
- }
-
- logOutFromOauthService(){
- if (!this.oauthService.hasValidAccessToken()){
- return;
- }
- this.oauthService.logOut();
- }
-
- loggedIn(){
- return this.oauthService.hasValidAccessToken();
- }
-
- cancelAdding(){
- this.logOutFromOauthService();
- this.resetNewIdProvider();
- this.resetScopes();
- this.newCredential.value = '';
- this.newCredential.name = '';
- }
-
-
- //Webfinger
-
- discoverIdProvider() {
- if (!this.isValidEmailforDiscovery()){
- return;
- }
- localStorage.setItem('userForCredential', this.identity.name);
- this.credentialService.getLink(this.webfingerEmail).subscribe (idProvider
=> {
- this.newIdProvider.url = (idProvider.links [0]).href;
- localStorage.setItem('newIdProviderURL', this.newIdProvider.url);
- this.newIdProvider.name =
this.getNewIdProviderName(this.newIdProvider.url);
- console.log(this.newIdProvider.url);
- this.webfingerEmail == '';
- this.getScopes();
- },
- error => {
- if (error.status == 404){
- this.errorMassage = this.getMessage("edit_credentials_ts@noAccount");
- }
- else{
- this.errorMassage =
this.getMessage("edit_credentials_ts@errorWrongAddress");
- }
- this.emailNotFoundAlertClosed = false;
- setTimeout(() => this.emailNotFoundAlertClosed = true, 20000);
- this.webfingerEmail = '';
- console.log (error);
- });
- }
-
- getScopes(){
- this.configureOauthService();
-
this.credentialService.getDiscoveryDocument(this.oauthService.issuer).subscribe(openidConfig
=> {
- openidConfig["scopes_supported"].forEach(scope => {
- const scopeInterface: Scope = {
- scope: scope,
- chosen: true,
- }
- this.scopes.push(scopeInterface)
- });
- localStorage.setItem("scopes", JSON.stringify(this.scopes));
- });
- }
-
- loadScopesFromLocalStorage(){
- this.scopes = [];
- var loadedScopes = localStorage.getItem("scopes");
- if (loadedScopes==null){
- return
- }
- loadedScopes.split(',{').forEach(scopeObject => {
- var scopeName = scopeObject.split(',')[0];
- var scopeChosen = scopeObject.split(',')[1].slice(0, -1);
- const scopeInterface: Scope = {
- scope: scopeName.split(':')[1].slice(1,-1),
- chosen: (/true/i).test(scopeChosen.split(':')[1]),
- }
- this.scopes.push(scopeInterface)
- }
- );
- }
-
- newIdProviderDiscovered(){
- if (this.newIdProvider.url == ''){
- return false;
- }
- return true;
- }
-
- isValidEmailforDiscovery(){
- if (!this.webfingerEmail.includes('@') && this.webfingerEmail != ''){
- return false;
- }
- return true;
- }
-
- loginFhgAccount(){
- this.configureOauthService();
- this.oauthService.loadDiscoveryDocumentAndLogin();
- }
-
- configureOauthService(){
- var authCodeFlowConfig =
this.credentialService.getOauthConfig(this.newIdProvider, this.scopes);
- this.oauthService.configure(authCodeFlowConfig);
- }
-
- cancelLinking(){
- this.resetNewIdProvider();
- this.resetScopes();
- this.webfingerEmail = '';
- }
-
- necessaryScope(scope){
- if (scope=="openid" || scope=="profile") {
- return true;
- }
- return false;
- }
-
- resetScopes(){
- localStorage.removeItem("scopes");
- this.scopes = [];
- }
-
//Internationalization
getMessage(key, sub?){
return this.languageService.getMessage(key, sub);
diff --git a/src/app/edit-identity/edit-identity.component.html
b/src/app/edit-identity/edit-identity.component.html
index ea5a10c..716bb4e 100644
--- a/src/app/edit-identity/edit-identity.component.html
+++ b/src/app/edit-identity/edit-identity.component.html
@@ -9,6 +9,15 @@
<h2 class="fa-2x"><i class="fa fa-user-circle pr-2"></i> {{
identity.name }}</h2>
</div>
</div>
+ <!--IdProvider-Discovery-->
+ <div *ngIf="!hasAttributes()" class="alert alert-primary alert-dismissible
fade show my-2" role="alert" >
+ <span class="fa fa-info"> </span> <b
class="ml-2">{{getMessage("edit_identity_html@noAttributes")}}</b><br/>
+ {{getMessage("edit_identity_html@importInfo")}}<br/>
+ <button class="btn btn-primary" [routerLink]="['/import-attributes',
identity.name ]">
+ <span class="fa fa-download"></span>
{{getMessage("edit_identity_html@linkAccount")}}
+ </button>
+ </div>
+
<!-- Attribute table -->
<div class="card-body">
<div>
diff --git a/src/app/edit-identity/edit-identity.component.ts
b/src/app/edit-identity/edit-identity.component.ts
index 6ed4e24..654d622 100644
--- a/src/app/edit-identity/edit-identity.component.ts
+++ b/src/app/edit-identity/edit-identity.component.ts
@@ -545,4 +545,8 @@ export class EditIdentityComponent implements OnInit {
return this.languageService.getMessage(key, sub);
}
+ hasAttributes(): boolean {
+ return this.attributes.length > 0;
+ }
+
}
diff --git a/src/app/identity-list/identity-list.component.ts
b/src/app/identity-list/identity-list.component.ts
index 8c44d79..94805a9 100644
--- a/src/app/identity-list/identity-list.component.ts
+++ b/src/app/identity-list/identity-list.component.ts
@@ -65,11 +65,7 @@ export class IdentityListComponent implements OnInit {
localStorage.setItem('credentialState',
this.route.snapshot.queryParams["state"]);
localStorage.setItem('credentialSession_State',
this.route.snapshot.queryParams["session_state"]);
var user = localStorage.getItem('userForCredential');
- this.router.navigate(['/edit-credentials', user]);
- }
- if (undefined !== this.route.snapshot.queryParams["logout"]){
- var user = localStorage.getItem('userForCredential');
- this.router.navigate(['/edit-credentials', user]);
+ this.router.navigate(['/import-attributes', user]);
}
if (!this.oidcService.inOpenIdFlow() && undefined ==
this.route.snapshot.queryParams["authz_request"]) {
this.oidcService.parseRouteParams(this.route.snapshot.queryParams);
diff --git a/src/app/import-attributes/import-attributes.component.ts
b/src/app/import-attributes/import-attributes.component.ts
index 4f610cb..3194490 100644
--- a/src/app/import-attributes/import-attributes.component.ts
+++ b/src/app/import-attributes/import-attributes.component.ts
@@ -10,7 +10,7 @@ import { IdProvider } from '../idProvider';
import { LoginOptions } from 'angular-oauth2-oidc';
import { Scope } from '../scope';
import { LanguageService } from '../language.service';
-
+import { ConfigService } from '../config.service';
@Component({
selector: 'app-import-attributes',
@@ -37,7 +37,8 @@ export class ImportAttributesComponent implements OnInit {
private router: Router,
private credentialService: CredentialService,
private oauthService: OAuthService,
- private languageService: LanguageService) { }
+ private languageService: LanguageService,
+ private configService: ConfigService) { }
ngOnInit(): void {
@@ -124,8 +125,12 @@ export class ImportAttributesComponent implements OnInit {
this.discoveringIdProvider = true;
localStorage.setItem('userForCredential', this.identity.name);
let account = this.webfingerEmail;
- if (this.webfingerEmail.substr(this.webfingerEmail.indexOf('@')+1) ===
'aisec.fraunhofer.de') {
- account = this.webfingerEmail.substr(0,
this.webfingerEmail.indexOf('@')+1) + 'as.aisec.fraunhofer.de';
+ if (this.configService.get().experiments) {
+ if (this.webfingerEmail.substr(this.webfingerEmail.indexOf('@')+1) ===
'aisec.fraunhofer.de') {
+ account = this.webfingerEmail.substr(0,
this.webfingerEmail.indexOf('@')+1) + 'as.aisec.fraunhofer.de';
+ } else if
(this.webfingerEmail.substr(this.webfingerEmail.indexOf('@')+1) === 'bfh.ch') {
+ account = this.webfingerEmail.substr(0,
this.webfingerEmail.indexOf('@')+1) + 'omejdn.nslab.ch';
+ }
}
this.credentialService.getLink(account).subscribe (idProvider => {
diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json
index 42be71a..a965f3f 100644
--- a/src/locales/en/messages.json
+++ b/src/locales/en/messages.json
@@ -22,6 +22,9 @@
"authorization_request_html@retry": "Retry",
"authorization_request_html@cancelRequest": "Cancel verification request",
"authorization_request_html@requestCancelled": "Request cancelled",
+ "import_attributes_html@import": "Import",
+ "import_attributes_html@importFor": "Import attributes for",
+ "import_attributes_html@confirm": "Confirm",
"edit_authorizations_html@manageAuths": "Manage authorizations for",
"edit_authorizations_html@authEntity": "Authorized Entity:",
"edit_authorizations_html@sharedAttributes": "Shared attributes:",
@@ -32,8 +35,8 @@
"edit_credentials_html@linkAccount": "Link account:",
"edit_credentials_html@notCompatible": "This account is not compatible
with re:claimID.",
"edit_credentials_html@info": "INFO",
- "edit_credentials_html@linkAccountInfo1": "It is possible to link your
external\naccounts with a re:claimID identity. To do so, enter you email
address\nbelow and click \"Check compatibility\".",
- "edit_credentials_html@linkAccountInfo2": "Not all external accounts
support linking to re:claimID identities.",
+ "edit_credentials_html@linkAccountInfo1": "It is possible to import
attributes from your external\naccounts into a re:claimID identity. To do so,
enter you email address\nbelow and click \"Import\".",
+ "edit_credentials_html@linkAccountInfo2": "Not all external accounts
support this feature.",
"edit_credentials_html@checkCompatability": "Check compatibility",
"edit_credentials_html@availableClaims": "Available claims to request:",
"edit_credentials_html@link": "Link",
@@ -50,6 +53,9 @@
"edit_credentials_ts@noAccount": "No account found with this email",
"edit_credentials_ts@errorWrongAddress": "An Error has occured - This may
have been caused by a wrong e-mail address.",
"edit_identity_html@basicInfo": "Basic user information",
+ "edit_identity_html@noAttributes": "This identity seems to not yet have
any attributes!",
+ "edit_identity_html@importInfo": "You can import attributes from an
existing online account or manually add your own below.",
+ "edit_identity_html@linkAccount": "Import attributes",
"edit_identity_html@standardScopes": "The attributes below correspond to
the standard scopes of the\nOpenID Connect specification: ``profile'',
``email'', ``phone'' and ``address''.",
"edit_identity_html@claimAsAttribute": "{{CREDVALUE}} issued by {{ISSUER}}
as attribute for ``{{CLAIMVALUE}}''",
"edit_identity_html@attribute": "Attribute",
@@ -93,8 +99,8 @@
"new_identity_html@usernameDuplicate": "An identity with this username
already exists.",
"new_identity_html@enterUsername": "Enter a username for your new
identity.",
"new_identity_html@username": "Username",
- "app_html@experimentalEnabled": "Epxerimental features enabled",
- "app_html@experimentalDisabled": "Epxerimental features disabled",
+ "app_html@experimentalEnabled": "Experimental features enabled",
+ "app_html@experimentalDisabled": "Experimental features disabled",
"claim@family_name": "Family name",
"claim@given_name": "Given name",
"claim@middle_name": "Middle name",
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [reclaim-ui] 358/459: clean up, (continued)
- [reclaim-ui] 358/459: clean up, gnunet, 2021/06/11
- [reclaim-ui] 386/459: fix import for browser plugin, other import may be broken, gnunet, 2021/06/11
- [reclaim-ui] 394/459: fix default selection, gnunet, 2021/06/11
- [reclaim-ui] 369/459: add code for straight attribute import, gnunet, 2021/06/11
- [reclaim-ui] 407/459: use share icon, gnunet, 2021/06/11
- [reclaim-ui] 397/459: fix address handling, gnunet, 2021/06/11
- [reclaim-ui] 406/459: allow authorization from edit component, gnunet, 2021/06/11
- [reclaim-ui] 376/459: updatte attribute info, gnunet, 2021/06/11
- [reclaim-ui] 371/459: attribute import done, gnunet, 2021/06/11
- [reclaim-ui] 404/459: fix, gnunet, 2021/06/11
- [reclaim-ui] 368/459: settings page, experiments tweaks,
gnunet <=
- [reclaim-ui] 395/459: fix, gnunet, 2021/06/11
- [reclaim-ui] 382/459: style adjustments, gnunet, 2021/06/11
- [reclaim-ui] 373/459: fix credential string lowercase, gnunet, 2021/06/11
- [reclaim-ui] 393/459: display all missing claims, gnunet, 2021/06/11
- [reclaim-ui] 380/459: quality of life improvements, gnunet, 2021/06/11
- [reclaim-ui] 383/459: better credential selection, gnunet, 2021/06/11
- [reclaim-ui] 396/459: relax attribute requirements, gnunet, 2021/06/11
- [reclaim-ui] 388/459: significantly simplify identity edit, gnunet, 2021/06/11
- [reclaim-ui] 418/459: more cleanup, gnunet, 2021/06/11
- [reclaim-ui] 431/459: Added translation using Weblate (Portuguese), gnunet, 2021/06/11