Wizard: add details for Satellite token expiration
This commit adds a more detailed information about when does the token used in Satellite command expire.
This commit is contained in:
parent
daa6e59bc0
commit
4192ada532
3 changed files with 61 additions and 37 deletions
|
|
@ -50,7 +50,7 @@ const SatelliteRegistration = () => {
|
|||
return (
|
||||
<>
|
||||
<SatelliteRegistrationCommand />
|
||||
<FormGroup label="Certificate authority (CA)" isRequired>
|
||||
<FormGroup label="Certificate authority (CA) for Satellite" isRequired>
|
||||
<FileUpload
|
||||
id="text-file-with-restrictions-example"
|
||||
type="text"
|
||||
|
|
@ -93,6 +93,12 @@ const SatelliteRegistration = () => {
|
|||
? 'Certificate was uploaded'
|
||||
: 'Drag and drop a valid certificate file or upload one'}
|
||||
</HelperTextItem>
|
||||
{(isRejected || validated !== 'success') && (
|
||||
<HelperTextItem>
|
||||
You can find this certificate at{' '}
|
||||
<i>http://satellite.example.com</i>/pub/katello-server-ca.crt
|
||||
</HelperTextItem>
|
||||
)}
|
||||
</HelperText>
|
||||
</FormHelperText>
|
||||
</FormGroup>
|
||||
|
|
|
|||
|
|
@ -112,6 +112,55 @@ type ValidationState = {
|
|||
ruleCharacters: HelperTextVariant;
|
||||
};
|
||||
|
||||
export function validateSatelliteToken(
|
||||
registrationCommand: string | undefined
|
||||
) {
|
||||
const errors: Record<string, string> = {};
|
||||
if (registrationCommand === '' || !registrationCommand) {
|
||||
errors.command = 'No registration command for Satellite registration';
|
||||
return errors;
|
||||
}
|
||||
|
||||
try {
|
||||
const match = registrationCommand?.match(
|
||||
/Bearer\s+([\w-]+\.[\w-]+\.[\w-]+)/
|
||||
);
|
||||
if (!match) {
|
||||
Object.assign(errors, { command: 'Invalid or missing token' });
|
||||
} else {
|
||||
const token = match[1];
|
||||
const decoded = jwtDecode(token);
|
||||
const currentTimeSeconds = Date.now() / 1000;
|
||||
const dayInSeconds = 86400;
|
||||
if (decoded.exp && decoded.exp < currentTimeSeconds + dayInSeconds) {
|
||||
const expirationDate = new Date(decoded.exp * 1000);
|
||||
let relativeTimeString;
|
||||
const secondsRemaining = decoded.exp - currentTimeSeconds;
|
||||
if (secondsRemaining < 1) {
|
||||
relativeTimeString = `is expired`;
|
||||
} else if (secondsRemaining < 60) {
|
||||
relativeTimeString = `will expire in less than a minute`;
|
||||
} else if (secondsRemaining < 3600) {
|
||||
const minutesLeft = Math.floor(secondsRemaining / 60);
|
||||
relativeTimeString = `will expire in approximately ${minutesLeft} minute${
|
||||
minutesLeft > 1 ? 's' : ''
|
||||
}`;
|
||||
} else {
|
||||
const hoursLeftExact = secondsRemaining / 3600;
|
||||
const numHours = Math.round(hoursLeftExact);
|
||||
relativeTimeString = `will expire in approximately ${numHours} hour${
|
||||
numHours > 1 ? 's' : ''
|
||||
}`;
|
||||
}
|
||||
errors.expired = `The token ${relativeTimeString}. Expiration date: ${expirationDate.toString()}. Check out the Satellite documentation to extend the Token lifetime.`;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
errors.command = 'Invalid or missing token';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
export function useRegistrationValidation(): StepValidation {
|
||||
const registrationType = useAppSelector(selectRegistrationType);
|
||||
const activationKey = useAppSelector(selectActivationKey);
|
||||
|
|
@ -154,44 +203,13 @@ export function useRegistrationValidation(): StepValidation {
|
|||
'Valid certificate must be present if you are registering Satellite.',
|
||||
});
|
||||
}
|
||||
if (registrationCommand === '' || !registrationCommand) {
|
||||
Object.assign(errors, {
|
||||
command: 'No registration command for Satellite registration',
|
||||
});
|
||||
}
|
||||
try {
|
||||
const match = registrationCommand?.match(
|
||||
/Bearer\s+([\w-]+\.[\w-]+\.[\w-]+)/
|
||||
);
|
||||
if (!match) {
|
||||
Object.assign(errors, { command: 'Invalid or missing token' });
|
||||
} else {
|
||||
const token = match[1];
|
||||
const decoded = jwtDecode(token);
|
||||
if (decoded.exp) {
|
||||
const currentTimeSeconds = Date.now() / 1000;
|
||||
const dayInSeconds = 86400;
|
||||
if (decoded.exp < currentTimeSeconds + dayInSeconds) {
|
||||
const expirationDate = new Date(decoded.exp * 1000);
|
||||
Object.assign(errors, {
|
||||
expired:
|
||||
'The token is already expired or will expire by next day. Expiration date: ' +
|
||||
expirationDate,
|
||||
});
|
||||
return {
|
||||
errors: errors,
|
||||
disabledNext: caCertificate === undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Object.assign(errors, { command: 'Invalid or missing token' });
|
||||
}
|
||||
const tokenErrors = validateSatelliteToken(registrationCommand);
|
||||
Object.assign(errors, tokenErrors);
|
||||
|
||||
return {
|
||||
errors: errors,
|
||||
disabledNext:
|
||||
Object.keys(errors).length > 0 || caCertificate === undefined,
|
||||
Object.keys(errors).filter((key) => key !== 'expired').length > 0,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ describe('Registration request generated correctly', () => {
|
|||
);
|
||||
|
||||
const expiredTokenHelper = await screen.findByText(
|
||||
/The token is already expired or will expire by next day. Expiration date/i
|
||||
/The token is expired. Expiration date/i
|
||||
);
|
||||
await waitFor(() => expect(expiredTokenHelper).toBeInTheDocument());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue