github.com/argoproj/argo-cd@v1.8.7/ui/src/app/settings/components/project-role-jwt-tokens/project-role-jwt-tokens.tsx (about)

     1  import {FormField, Tooltip} from 'argo-ui';
     2  import * as React from 'react';
     3  import {Form, FormApi, Text} from 'react-form';
     4  
     5  import {Consumer, ContextApis} from '../../../shared/context';
     6  import {JwtToken} from '../../../shared/models';
     7  import {CreateJWTTokenParams, DeleteJWTTokenParams} from '../../../shared/services';
     8  import {convertExpiresInToSeconds, validExpiresIn} from '../utils';
     9  
    10  interface ProjectRoleJWTTokensProps {
    11      projName: string;
    12      roleName: string;
    13      tokens: JwtToken[];
    14      token: string;
    15      createJWTToken: (params: CreateJWTTokenParams) => void;
    16      deleteJWTToken: (params: DeleteJWTTokenParams) => void;
    17      hideJWTToken: () => void;
    18      getApi?: (formApi: FormApi) => void;
    19  }
    20  
    21  require('./project-role-jwt-tokens.scss');
    22  
    23  export const ProjectRoleJWTTokens = (props: ProjectRoleJWTTokensProps) => {
    24      return (
    25          <Consumer>
    26              {ctx => (
    27                  <React.Fragment>
    28                      <h4>JWT Tokens</h4>
    29                      <div>Generate JWT tokens to bind to this role</div>
    30                      {props.tokens && props.tokens.length > 0 && (
    31                          <div className='argo-table-list'>
    32                              <div className='argo-table-list__head'>
    33                                  <div className='row'>
    34                                      <div className='columns small-3'>ID</div>
    35                                      <div className='columns small-4'>ISSUED AT</div>
    36                                      <div className='columns small-4'>EXPIRES AT</div>
    37                                  </div>
    38                              </div>
    39                              {props.tokens.map(jwToken => renderJWTRow(props, ctx, jwToken))}
    40                          </div>
    41                      )}
    42                      <Form
    43                          getApi={props.getApi}
    44                          defaultValues={{expiresIn: ''}}
    45                          validateError={(params: any) => ({
    46                              expiresIn: !validExpiresIn(params.expiresIn) && 'Must be in the "[0-9]+[smhd]" format. For example, "12h", "7d".'
    47                          })}>
    48                          {api => (
    49                              <form onSubmit={api.submitForm} role='form' className='width-control'>
    50                                  <div className='white-box'>
    51                                      <div className='argo-table-list'>
    52                                          <div className='argo-form-row'>
    53                                              <FormField formApi={api} label='Token ID' field='id' component={Text} />
    54                                          </div>
    55                                          <div className='argo-form-row'>
    56                                              <FormField formApi={api} label='Expires In' field='expiresIn' component={Text} />
    57                                          </div>
    58  
    59                                          <div>
    60                                              <button className='argo-button argo-button--base' onClick={() => createJWTToken(props, api, ctx)}>
    61                                                  Create
    62                                              </button>
    63                                          </div>
    64                                      </div>
    65                                  </div>
    66  
    67                                  {props.token && (
    68                                      <div className='argo-table-list'>
    69                                          <div className='argo-table-list__head'>
    70                                              <div className='row'>
    71                                                  <div className='columns small-3'>NEW TOKEN</div>
    72                                              </div>
    73                                          </div>
    74                                          <div className='argo-table-list__row'>
    75                                              <div className='white-box'>
    76                                                  <p style={{overflowWrap: 'break-word'}}>
    77                                                      {props.token}
    78                                                      <i className='fa fa-times project-role-jwt-tokens__hide-token' onClick={() => props.hideJWTToken()} />
    79                                                  </p>
    80                                              </div>
    81                                          </div>
    82                                      </div>
    83                                  )}
    84                              </form>
    85                          )}
    86                      </Form>
    87                  </React.Fragment>
    88              )}
    89          </Consumer>
    90      );
    91  };
    92  
    93  async function createJWTToken(props: ProjectRoleJWTTokensProps, api: FormApi, ctx: any) {
    94      if (api.errors.expiresIn) {
    95          return;
    96      }
    97      const project = props.projName;
    98      const role = props.roleName;
    99      const expiresIn = convertExpiresInToSeconds(api.values.expiresIn);
   100      let expiresInPrompt = 'has no expiration';
   101      if (expiresIn !== 0) {
   102          expiresInPrompt = 'expires in ' + api.values.expiresIn;
   103      }
   104      const id = api.values.id;
   105      const nameContext = id === undefined || id === '' ? ` has no token ID and ` : ` has token ID '${id}' and `;
   106      const confirmed = await ctx.popup.confirm(
   107          'Create JWT Token',
   108          `Are you sure you want to create a JWT token that ${nameContext}${expiresInPrompt} for role '${role}' in project '${project}'?`
   109      );
   110      if (confirmed) {
   111          props.createJWTToken({project, role, expiresIn, id} as CreateJWTTokenParams);
   112          api.values.expiresIn = '';
   113          api.values.id = '';
   114      }
   115  }
   116  
   117  async function deleteJWTToken(props: ProjectRoleJWTTokensProps, iat: number, ctx: any, id: string) {
   118      const confirmed = await ctx.popup.confirm('Delete JWT Token', `Are you sure you want to delete token ID '${id}' for role '${props.roleName}' in project '${props.projName}'?`);
   119      if (confirmed) {
   120          props.deleteJWTToken({project: props.projName, role: props.roleName, iat} as DeleteJWTTokenParams);
   121      }
   122  }
   123  
   124  function renderJWTRow(props: ProjectRoleJWTTokensProps, ctx: ContextApis, jwToken: JwtToken): React.ReactFragment {
   125      const issuedAt = new Date(jwToken.iat * 1000).toISOString();
   126      const expiresAt = jwToken.exp == null ? 'Never' : new Date(jwToken.exp * 1000).toISOString();
   127  
   128      return (
   129          <React.Fragment>
   130              <div className='argo-table-list__row' key={`${jwToken.iat}`}>
   131                  <div className='row'>
   132                      <Tooltip content={jwToken.id}>
   133                          <div className='columns small-3'>{jwToken.id}</div>
   134                      </Tooltip>
   135                      <Tooltip content={issuedAt}>
   136                          <div className='columns small-4'>{issuedAt}</div>
   137                      </Tooltip>
   138                      <Tooltip content={expiresAt}>
   139                          <div className='columns small-4'>{expiresAt}</div>
   140                      </Tooltip>
   141                      <Tooltip content='Delete Token'>
   142                          <div className='columns small-1'>
   143                              <i className='fa fa-times' onClick={() => deleteJWTToken(props, jwToken.iat, ctx, jwToken.id)} style={{cursor: 'pointer'}} />
   144                          </div>
   145                      </Tooltip>
   146                  </div>
   147              </div>
   148          </React.Fragment>
   149      );
   150  }