Merge pull request #1440 from scm-manager/feature/unify_key_views
Feature/unify key views
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Added
|
||||
- Add tooltips to short links on repository overview ([#1441](https://github.com/scm-manager/scm-manager/pull/1441))
|
||||
- Show the date of the last commit for branches in the frontend ([#1439](https://github.com/scm-manager/scm-manager/pull/1439))
|
||||
- Unify and add description to key view across user settings ([#1440](https://github.com/scm-manager/scm-manager/pull/1440))
|
||||
|
||||
## [2.10.1] - 2020-11-24
|
||||
### Fixed
|
||||
|
||||
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 285 KiB |
@@ -13,7 +13,7 @@ eingegeben werden. Danach muss das neue Passwort zweimal eingegeben werden.
|
||||
|
||||
## Öffentliche Schlüssel
|
||||
|
||||
Zum Prüfen von Signaturen für z. B. Commits können hier die entsprechenden öffentlichen Schlüssel hinterlegt werden.
|
||||
Zum Prüfen von Signaturen für z. B. Commits können hier die entsprechenden öffentlichen GPG Schlüssel hinterlegt werden.
|
||||
Zudem können hier die vom SCM-Manager erstellten Signaturschlüssel heruntergeladen werden.
|
||||
|
||||
## API Schlüssel
|
||||
|
||||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 237 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 250 KiB |
|
Before Width: | Height: | Size: 245 KiB After Width: | Height: | Size: 270 KiB |
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 275 KiB |
@@ -11,9 +11,9 @@ Here the password for the current account can be changed when it is a local acco
|
||||
external system). To authorize the change, the current password has to be put first. Then the new password has to be
|
||||
entered twice.
|
||||
|
||||
## Öffentliche Schlüssel
|
||||
## Public Keys
|
||||
|
||||
To check signatures for example for commits, public keys can be stored here. Additionally the keys created by
|
||||
To check signatures (for example for commits), gpg public keys can be stored here. Additionally the keys created by
|
||||
SCM-Manager can be accessed here, too.
|
||||
|
||||
## API keys
|
||||
|
||||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 246 KiB |
|
Before Width: | Height: | Size: 240 KiB After Width: | Height: | Size: 263 KiB |
@@ -79,15 +79,22 @@
|
||||
}
|
||||
},
|
||||
"publicKey": {
|
||||
"subtitle": "Öffentliche Schlüssel",
|
||||
"description": "Zum Prüfen von Signaturen für z. B. Commits können hier die entsprechenden öffentlichen GPG Schlüssel hinterlegt werden. Zudem können hier die vom SCM-Manager erstellten Signaturschlüssel heruntergeladen werden.",
|
||||
"noStoredKeys": "Es wurden keine Schlüssel gefunden.",
|
||||
"displayName": "Anzeigename",
|
||||
"raw": "Schlüssel",
|
||||
"created": "Eingetragen an",
|
||||
"addKey": "Schlüssel hinzufügen",
|
||||
"raw": "Schlüssel",
|
||||
"download": "Herunterladen",
|
||||
"delete": "Löschen",
|
||||
"download": "Herunterladen"
|
||||
"addSubtitle": "Neuen Schlüssel hinzufügen",
|
||||
"addKey": "Schlüssel hinzufügen"
|
||||
},
|
||||
"apiKey": {
|
||||
"subtitle": "API Schlüssel",
|
||||
"text1": "Erstelle und verwalte Personal Access Token um auf die REST API zuzugreifen oder diese als Passwort für SCM-Clients zu nutzen. Die Rechte der Token sind auf Repositories und die gewählte Rolle beschränkt.",
|
||||
"manageRoles": "Sie können die Rollenberechtigungen in der Administration unter „Berechtigungsrollen“ einsehen und neue Rollen anlegen.",
|
||||
"text2": "Um den Token in REST-Abfragen zu nutzen, übergeben Sie diesen als Cookie mit dem Namen „X-Bearer-Token“. Sie können den Token auch anstelle Ihres Passworts nutzen, um sich mit SCM-Clients anzumelden.",
|
||||
"noStoredKeys": "Es wurden keine Schlüssel gefunden.",
|
||||
"displayName": "Anzeigename",
|
||||
"permissionRole": {
|
||||
@@ -95,12 +102,10 @@
|
||||
"help": "Mit der Rolle können Sie die Berechtigung für diesen Schlüssel einschränken"
|
||||
},
|
||||
"created": "Eingetragen an",
|
||||
"addSubtitle": "Neuen Schlüssel hinzufügen",
|
||||
"addKey": "Schlüssel hinzufügen",
|
||||
"delete": "Löschen",
|
||||
"download": "Herunterladen",
|
||||
"text1": "Erstelle und verwalte Personal Access Token um auf die REST API zuzugreifen oder diese als Passwort für SCM-Clients zu nutzen. Die Rechte der Token sind auf Repositories und die gewählte Rolle beschränkt.",
|
||||
"manageRoles": "Sie können die Rollenberechtigungen in der Administration unter „Berechtigungsrollen“ einsehen und neue Rollen anlegen.",
|
||||
"text2": "Um den Token in REST-Abfragen zu nutzen, übergeben Sie diesen als Cookie mit dem Namen „X-Bearer-Token“. Sie können den Token auch anstelle Ihres Passworts nutzen, um sich mit SCM-Clients anzumelden.",
|
||||
"modal": {
|
||||
"title": "Schlüssel erzeugt",
|
||||
"text1": "Ihr neuer API-Schlüssel ist bereit. Sie können diesen als Token für Zugriffe auf die REST-Schnittstelle nutzen oder anstelle Ihres Passworts zum Login mit SCM-Clients nutzen.",
|
||||
|
||||
@@ -79,15 +79,22 @@
|
||||
}
|
||||
},
|
||||
"publicKey": {
|
||||
"subtitle": "Public Keys",
|
||||
"description": "To check signatures (for example for commits), gpg public keys can be stored here. Additionally the keys created by SCM-Manager can be accessed here, too.",
|
||||
"noStoredKeys": "No keys found.",
|
||||
"displayName": "Display Name",
|
||||
"raw": "Key",
|
||||
"created": "Created on",
|
||||
"addKey": "Add key",
|
||||
"raw": "Key",
|
||||
"download": "Download",
|
||||
"delete": "Delete",
|
||||
"download": "Download"
|
||||
"addSubtitle": "Add new key",
|
||||
"addKey": "Add key"
|
||||
},
|
||||
"apiKey": {
|
||||
"subtitle": "API Keys",
|
||||
"text1": "Create and manage personal access tokens to access the REST API or use as a password for SCM clients. The privileges of these tokens are limited to repositories and the selected role.",
|
||||
"manageRoles": "You may view and create roles in the administration view “Permission Roles”.",
|
||||
"text2": "To use the token in a REST request, pass it as a cookie named “X-Bearer-Token”. You may use the token as your password for SCM clients, too.",
|
||||
"noStoredKeys": "No keys found.",
|
||||
"displayName": "Display Name",
|
||||
"permissionRole": {
|
||||
@@ -95,12 +102,10 @@
|
||||
"help": "The api key will be restricted to permissions of this role"
|
||||
},
|
||||
"created": "Created on",
|
||||
"addSubtitle": "Add new key",
|
||||
"addKey": "Add key",
|
||||
"delete": "Delete",
|
||||
"download": "Download",
|
||||
"text1": "Create and manage personal access tokens to access the REST API or use as a password for SCM clients. The privileges of these tokens are limited to repositories and the selected role.",
|
||||
"manageRoles": "You may view and create roles in the administration view “Permission Roles”.",
|
||||
"text2": "To use the token in a REST request, pass it as a cookie named “X-Bearer-Token”. You may use the token as your password for SCM clients, too.",
|
||||
"modal": {
|
||||
"title": "Key created",
|
||||
"text1": "Your new API key is ready. You can use it as a bearer token for REST calls or as a password for SCM clients.",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
import React, { FC, useEffect, useState } from "react";
|
||||
import { apiClient, ErrorNotification, InputField, Level, Loading, SubmitButton } from "@scm-manager/ui-components";
|
||||
import { apiClient, ErrorNotification, InputField, Level, Loading, SubmitButton, Subtitle } from "@scm-manager/ui-components";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { CONTENT_TYPE_API_KEY } from "./SetApiKeys";
|
||||
import { connect } from "react-redux";
|
||||
@@ -105,6 +105,8 @@ const AddApiKey: FC<Props> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<hr />
|
||||
<Subtitle subtitle={t("apiKey.addSubtitle")} />
|
||||
{newKeyModal}
|
||||
<InputField label={t("apiKey.displayName")} value={displayName} onChange={setDisplayName} />
|
||||
<RoleSelector
|
||||
|
||||
@@ -39,8 +39,8 @@ export const ApiKeyEntry: FC<Props> = ({ apiKey, onDelete }) => {
|
||||
if (apiKey?._links?.delete) {
|
||||
deleteButton = (
|
||||
<a className="level-item" onClick={() => onDelete((apiKey._links.delete as Link).href)}>
|
||||
<span className="icon is-small">
|
||||
<Icon name="trash" className="fas" title={t("apiKey.delete")} />
|
||||
<span className="icon">
|
||||
<Icon name="trash" title={t("apiKey.delete")} color="inherit" />
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
@@ -52,7 +52,7 @@ export const ApiKeyEntry: FC<Props> = ({ apiKey, onDelete }) => {
|
||||
<td>{apiKey.displayName}</td>
|
||||
<td>{apiKey.permissionRole}</td>
|
||||
<td className="is-hidden-mobile">
|
||||
<DateFromNow date={apiKey.created}/>
|
||||
<DateFromNow date={apiKey.created} />
|
||||
</td>
|
||||
<td className="is-darker">{deleteButton}</td>
|
||||
</tr>
|
||||
|
||||
@@ -25,11 +25,10 @@
|
||||
import { Collection, Links, User, Me } from "@scm-manager/ui-types";
|
||||
import React, { FC, useEffect, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { apiClient, ErrorNotification, Loading } from "@scm-manager/ui-components";
|
||||
import { apiClient, ErrorNotification, Loading, Subtitle } from "@scm-manager/ui-components";
|
||||
import ApiKeyTable from "./ApiKeyTable";
|
||||
import AddApiKey from "./AddApiKey";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
|
||||
export type ApiKeysCollection = Collection & {
|
||||
_embedded: {
|
||||
@@ -51,10 +50,6 @@ type Props = {
|
||||
user: User | Me;
|
||||
};
|
||||
|
||||
const Subtitle = styled.div`
|
||||
margin-bottom: 1rem;
|
||||
`;
|
||||
|
||||
const SetApiKeys: FC<Props> = ({ user }) => {
|
||||
const [t] = useTranslation("users");
|
||||
const [error, setError] = useState<undefined | Error>();
|
||||
@@ -94,14 +89,13 @@ const SetApiKeys: FC<Props> = ({ user }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={"media-content"}>
|
||||
<p>{t("apiKey.text1")} <Link to={"/admin/roles/"}>{t("apiKey.manageRoles")}</Link></p>
|
||||
<p>{t("apiKey.text2")}</p>
|
||||
</div>
|
||||
<hr />
|
||||
<Subtitle subtitle={t("apiKey.subtitle")} />
|
||||
<p>
|
||||
{t("apiKey.text1")} <Link to={"/admin/roles/"}>{t("apiKey.manageRoles")}</Link>
|
||||
</p>
|
||||
<p>{t("apiKey.text2")}</p>
|
||||
<br />
|
||||
<ApiKeyTable apiKeys={apiKeys} onDelete={onDelete} />
|
||||
<hr />
|
||||
<Subtitle className={"media-content"}><h2 className={"title is-4"}>Create new key</h2></Subtitle>
|
||||
{createLink && <AddApiKey createLink={createLink} refresh={fetchApiKeys} />}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
import React, { FC, useState } from "react";
|
||||
import { User, Link, Links, Collection } from "@scm-manager/ui-types/src";
|
||||
import {
|
||||
ErrorNotification,
|
||||
InputField,
|
||||
@@ -31,7 +30,8 @@ import {
|
||||
Textarea,
|
||||
SubmitButton,
|
||||
apiClient,
|
||||
Loading
|
||||
Loading,
|
||||
Subtitle
|
||||
} from "@scm-manager/ui-components";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { CONTENT_TYPE_PUBLIC_KEY } from "./SetPublicKeys";
|
||||
@@ -77,6 +77,8 @@ const AddPublicKey: FC<Props> = ({ createLink, refresh }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<hr />
|
||||
<Subtitle subtitle={t("publicKey.addSubtitle")} />
|
||||
<InputField label={t("publicKey.displayName")} value={displayName} onChange={setDisplayName} />
|
||||
<Textarea name="raw" label={t("publicKey.raw")} value={raw} onChange={setRaw} />
|
||||
<Level
|
||||
|
||||
@@ -22,24 +22,28 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import React, {FC} from "react";
|
||||
import {DateFromNow, DeleteButton} from "@scm-manager/ui-components";
|
||||
import {PublicKey} from "./SetPublicKeys";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {Link} from "@scm-manager/ui-types";
|
||||
import React, { FC } from "react";
|
||||
import { DateFromNow, Icon } from "@scm-manager/ui-components";
|
||||
import { PublicKey } from "./SetPublicKeys";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "@scm-manager/ui-types";
|
||||
|
||||
type Props = {
|
||||
publicKey: PublicKey;
|
||||
onDelete: (link: string) => void;
|
||||
};
|
||||
|
||||
export const PublicKeyEntry: FC<Props> = ({publicKey, onDelete}) => {
|
||||
export const PublicKeyEntry: FC<Props> = ({ publicKey, onDelete }) => {
|
||||
const [t] = useTranslation("users");
|
||||
|
||||
let deleteButton;
|
||||
if (publicKey?._links?.delete) {
|
||||
deleteButton = (
|
||||
<DeleteButton label={t("publicKey.delete")} action={() => onDelete((publicKey._links.delete as Link).href)}/>
|
||||
<a className="level-item" onClick={() => onDelete((publicKey._links.delete as Link).href)}>
|
||||
<span className="icon">
|
||||
<Icon name="trash" title={t("publicKey.delete")} color="inherit" />
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -48,11 +52,18 @@ export const PublicKeyEntry: FC<Props> = ({publicKey, onDelete}) => {
|
||||
<tr>
|
||||
<td>{publicKey.displayName}</td>
|
||||
<td className="is-hidden-mobile">
|
||||
<DateFromNow date={publicKey.created}/>
|
||||
<DateFromNow date={publicKey.created} />
|
||||
</td>
|
||||
<td className="is-hidden-mobile">{publicKey._links?.raw ?
|
||||
<a href={(publicKey._links.raw as Link).href}>{publicKey.id}</a> : publicKey.id}</td>
|
||||
<td>{deleteButton}</td>
|
||||
<td className="is-hidden-mobile">
|
||||
{publicKey._links?.raw ? (
|
||||
<a title={t("publicKey.download")} href={(publicKey._links.raw as Link).href}>
|
||||
{publicKey.id}
|
||||
</a>
|
||||
) : (
|
||||
publicKey.id
|
||||
)}
|
||||
</td>
|
||||
<td className="is-darker">{deleteButton}</td>
|
||||
</tr>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
|
||||
import { Collection, Link, Links, User, Me } from "@scm-manager/ui-types";
|
||||
import React, { FC, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import AddPublicKey from "./AddPublicKey";
|
||||
import PublicKeyTable from "./PublicKeyTable";
|
||||
import { apiClient, ErrorNotification, Loading } from "@scm-manager/ui-components";
|
||||
import { apiClient, ErrorNotification, Loading, Subtitle } from "@scm-manager/ui-components";
|
||||
|
||||
export type PublicKeysCollection = Collection & {
|
||||
_embedded: {
|
||||
@@ -49,6 +50,7 @@ type Props = {
|
||||
};
|
||||
|
||||
const SetPublicKeys: FC<Props> = ({ user }) => {
|
||||
const [t] = useTranslation("users");
|
||||
const [error, setError] = useState<undefined | Error>();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [publicKeys, setPublicKeys] = useState<PublicKeysCollection | undefined>(undefined);
|
||||
@@ -86,6 +88,9 @@ const SetPublicKeys: FC<Props> = ({ user }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Subtitle subtitle={t("publicKey.subtitle")} />
|
||||
<p>{t("publicKey.description")}</p>
|
||||
<br />
|
||||
<PublicKeyTable publicKeys={publicKeys} onDelete={onDelete} />
|
||||
{createLink && <AddPublicKey createLink={createLink} refresh={fetchPublicKeys} />}
|
||||
</>
|
||||
|
||||