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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<SatelliteRegistrationCommand />
|
<SatelliteRegistrationCommand />
|
||||||
<FormGroup label="Certificate authority (CA)" isRequired>
|
<FormGroup label="Certificate authority (CA) for Satellite" isRequired>
|
||||||
<FileUpload
|
<FileUpload
|
||||||
id="text-file-with-restrictions-example"
|
id="text-file-with-restrictions-example"
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -93,6 +93,12 @@ const SatelliteRegistration = () => {
|
||||||
? 'Certificate was uploaded'
|
? 'Certificate was uploaded'
|
||||||
: 'Drag and drop a valid certificate file or upload one'}
|
: 'Drag and drop a valid certificate file or upload one'}
|
||||||
</HelperTextItem>
|
</HelperTextItem>
|
||||||
|
{(isRejected || validated !== 'success') && (
|
||||||
|
<HelperTextItem>
|
||||||
|
You can find this certificate at{' '}
|
||||||
|
<i>http://satellite.example.com</i>/pub/katello-server-ca.crt
|
||||||
|
</HelperTextItem>
|
||||||
|
)}
|
||||||
</HelperText>
|
</HelperText>
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,55 @@ type ValidationState = {
|
||||||
ruleCharacters: HelperTextVariant;
|
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 {
|
export function useRegistrationValidation(): StepValidation {
|
||||||
const registrationType = useAppSelector(selectRegistrationType);
|
const registrationType = useAppSelector(selectRegistrationType);
|
||||||
const activationKey = useAppSelector(selectActivationKey);
|
const activationKey = useAppSelector(selectActivationKey);
|
||||||
|
|
@ -154,44 +203,13 @@ export function useRegistrationValidation(): StepValidation {
|
||||||
'Valid certificate must be present if you are registering Satellite.',
|
'Valid certificate must be present if you are registering Satellite.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (registrationCommand === '' || !registrationCommand) {
|
const tokenErrors = validateSatelliteToken(registrationCommand);
|
||||||
Object.assign(errors, {
|
Object.assign(errors, tokenErrors);
|
||||||
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' });
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
errors: errors,
|
errors: errors,
|
||||||
disabledNext:
|
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(
|
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());
|
await waitFor(() => expect(expiredTokenHelper).toBeInTheDocument());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue