Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions web/packages/teleport/src/Account/Account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ import {
import ReAuthenticate from 'teleport/components/ReAuthenticate';
import { RemoveDialog } from 'teleport/components/MfaDeviceList';

import { MfaChallengeScope } from 'teleport/services/auth/auth';

import cfg from 'teleport/config';

import { DeviceUsage } from 'teleport/services/mfa';
Expand Down Expand Up @@ -232,7 +230,6 @@ export function Account({
onAuthenticated={setToken}
onClose={hideReAuthenticate}
actionText="registering a new device"
challengeScope={MfaChallengeScope.MANAGE_DEVICES}
/>
)}
{EnterpriseComponent && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { PasskeyIcons } from 'teleport/components/PasskeyIcons';

import { DialogHeader } from 'teleport/Account/DialogHeader';
import useReAuthenticate from 'teleport/components/ReAuthenticate/useReAuthenticate';
import auth, { MfaChallengeScope } from 'teleport/services/auth/auth';
import auth from 'teleport/services/auth/auth';
import { DeviceUsage } from 'teleport/services/mfa';
import useTeleport from 'teleport/useTeleport';

Expand Down Expand Up @@ -126,15 +126,13 @@ export function ReauthenticateStep({
onClose,
onAuthenticated: onAuthenticatedProp,
}: ReauthenticateStepProps) {
const challengeScope = MfaChallengeScope.MANAGE_DEVICES;
const onAuthenticated = (privilegeToken: string) => {
onAuthenticatedProp(privilegeToken);
next();
};
const { attempt, clearAttempt, submitWithTotp, submitWithWebauthn } =
useReAuthenticate({
onAuthenticated,
challengeScope,
});
const mfaOptions = createMfaOptions({
auth2faType,
Expand All @@ -155,7 +153,7 @@ export function ReauthenticateStep({
e.preventDefault();
if (!validator.validate()) return;
if (mfaOption === 'webauthn') {
submitWithWebauthn(challengeScope);
submitWithWebauthn();
}
if (mfaOption === 'otp') {
submitWithTotp(authCode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import React from 'react';

import { MfaChallengeScope } from 'teleport/services/auth/auth';

import { State } from './useReAuthenticate';
import { ReAuthenticate } from './ReAuthenticate';

Expand Down Expand Up @@ -49,5 +47,4 @@ const props: State = {
onClose: () => null,
auth2faType: 'on',
actionText: 'performing this action',
challengeScope: MfaChallengeScope.UNSPECIFIED,
};
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export function ReAuthenticate({
auth2faType,
preferredMfaType,
actionText,
challengeScope,
}: State) {
const [otpToken, setOtpToken] = useState('');
const mfaOptions = createMfaOptions({
Expand All @@ -61,7 +60,7 @@ export function ReAuthenticate({
e.preventDefault();

if (mfaOption?.value === 'webauthn') {
submitWithWebauthn(challengeScope);
submitWithWebauthn();
}
if (mfaOption?.value === 'otp') {
submitWithTotp(otpToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import type { MfaAuthnResponse } from 'teleport/services/mfa';
// token, and after successfully obtaining the token, the function
// `onAuthenticated` will be called with this token.
export default function useReAuthenticate(props: Props) {
const { onClose, actionText = defaultActionText, challengeScope } = props;
const { onClose, actionText = defaultActionText } = props;

// Note that attempt state "success" is not used or required.
// After the user submits, the control is passed back
Expand All @@ -53,12 +53,12 @@ export default function useReAuthenticate(props: Props) {
.catch(handleError);
}

function submitWithWebauthn(scope: MfaChallengeScope) {
function submitWithWebauthn() {
setAttempt({ status: 'processing' });

if ('onMfaResponse' in props) {
auth
.getWebauthnResponse(scope)
.getWebauthnResponse(props.challengeScope)
.then(webauthnResponse =>
props.onMfaResponse({ webauthn_response: webauthnResponse })
)
Expand All @@ -67,7 +67,7 @@ export default function useReAuthenticate(props: Props) {
}

auth
.createPrivilegeTokenWithWebauthn(scope)
.createPrivilegeTokenWithWebauthn()
.then(props.onAuthenticated)
.catch((err: Error) => {
// This catches a webauthn frontend error that occurs on Firefox and replaces it with a more helpful error message.
Expand Down Expand Up @@ -97,7 +97,6 @@ export default function useReAuthenticate(props: Props) {
auth2faType: cfg.getAuth2faType(),
preferredMfaType: cfg.getPreferredMfaType(),
actionText,
challengeScope,
onClose,
};
}
Expand All @@ -116,19 +115,17 @@ type BaseProps = {
*
* */
actionText?: string;
/**
* The MFA challenge scope of the action to perform, as defined in webauthn.proto.
*
* TODO(Joerger): change to required field once provided by /e references
*/
challengeScope?: MfaChallengeScope;
};

// MfaResponseProps defines a function
// that accepts a MFA response. No
// authentication has been done at this point.
type MfaResponseProps = BaseProps & {
onMfaResponse(res: MfaAuthnResponse): void;
/**
* The MFA challenge scope of the action to perform, as defined in webauthn.proto.
*/
challengeScope: MfaChallengeScope;
onAuthenticated?: never;
};

Expand All @@ -139,6 +136,8 @@ type MfaResponseProps = BaseProps & {
type DefaultProps = BaseProps & {
onAuthenticated(privilegeTokenId: string): void;
onMfaResponse?: never;
// TODO(Joerger): change type to 'never' once it is no longer expected in /e
challengeScope?: MfaChallengeScope;
};

export type Props = MfaResponseProps | DefaultProps;
Expand Down
15 changes: 9 additions & 6 deletions web/packages/teleport/src/services/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,15 @@ const auth = {
);
},

createPrivilegeTokenWithWebauthn(scope: MfaChallengeScope) {
return auth.fetchWebAuthnChallenge({ scope }).then(res =>
api.post(cfg.api.createPrivilegeTokenPath, {
webauthnAssertionResponse: makeWebauthnAssertionResponse(res),
})
);
createPrivilegeTokenWithWebauthn() {
// Creating privilege tokens always expects the MANAGE_DEVICES webauthn scope.
return auth
.fetchWebAuthnChallenge({ scope: MfaChallengeScope.MANAGE_DEVICES })
.then(res =>
api.post(cfg.api.createPrivilegeTokenPath, {
webauthnAssertionResponse: makeWebauthnAssertionResponse(res),
})
);
},

createRestrictedPrivilegeToken() {
Expand Down