fix(client/api): ms trophy validation (#51892)
parent
89f0310372
commit
9b50d54001
|
@ -719,14 +719,42 @@ function createMsTrophyChallengeCompleted(app) {
|
|||
}
|
||||
|
||||
const { msTrophyId = '' } = challenge;
|
||||
const msTrophyApiUrl = `https://learn.microsoft.com/api/gamestatus/achievements/${msTrophyId}?username=${msUsername}&locale=en-us`;
|
||||
const msApiRes = await fetch(msTrophyApiUrl);
|
||||
const msTrophyJson = await msApiRes.json();
|
||||
|
||||
if (!msApiRes.ok || msTrophyJson.awardType !== 'Trophy') {
|
||||
const msProfileApi = `https://learn.microsoft.com/api/profiles/${msUsername}`;
|
||||
const msProfileApiRes = await fetch(msProfileApi);
|
||||
const msProfileJson = await msProfileApiRes.json();
|
||||
|
||||
if (!msProfileApiRes.ok || !msProfileJson.userId) {
|
||||
return res.status(403).json({
|
||||
type: 'error',
|
||||
message: 'flash.ms.trophy.err-3',
|
||||
message: 'flash.ms.profile.err',
|
||||
variables: {
|
||||
msUsername
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const { userId } = msProfileJson;
|
||||
|
||||
const msGameStatusApi = `https://learn.microsoft.com/api/gamestatus/${userId}`;
|
||||
const msGameStatusApiRes = await fetch(msGameStatusApi);
|
||||
const msGameStatusJson = await msGameStatusApiRes.json();
|
||||
|
||||
if (!msGameStatusApiRes.ok) {
|
||||
return res.status(403).json({
|
||||
type: 'error',
|
||||
message: 'flash.ms.trophy.err-3'
|
||||
});
|
||||
}
|
||||
|
||||
const hasEarnedTrophy = msGameStatusJson.achievements?.some(
|
||||
a => a.awardUid === msTrophyId
|
||||
);
|
||||
|
||||
if (!hasEarnedTrophy) {
|
||||
return res.status(403).json({
|
||||
type: 'error',
|
||||
message: 'flash.ms.trophy.err-4',
|
||||
variables: {
|
||||
msUsername
|
||||
}
|
||||
|
@ -735,7 +763,7 @@ function createMsTrophyChallengeCompleted(app) {
|
|||
|
||||
const completedChallenge = pick(body, ['id']);
|
||||
|
||||
completedChallenge.solution = msTrophyApiUrl;
|
||||
completedChallenge.solution = msGameStatusApi;
|
||||
completedChallenge.completedDate = Date.now();
|
||||
|
||||
try {
|
||||
|
@ -765,7 +793,7 @@ function createMsTrophyChallengeCompleted(app) {
|
|||
log(e);
|
||||
return res.status(500).json({
|
||||
type: 'error',
|
||||
message: 'flash.ms.trophy.err-4'
|
||||
message: 'flash.ms.trophy.err-5'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -732,11 +732,15 @@
|
|||
"unlinked": "The link to your Microsoft username has been removed.",
|
||||
"unlink-err": "Something went wrong trying to remove the link to your Microsoft username."
|
||||
},
|
||||
"profile": {
|
||||
"err": "We could not find a Microsoft user ID for Microsoft user \"{{msUsername}}\""
|
||||
},
|
||||
"trophy": {
|
||||
"err-1": "We could not find a Microsoft username associated with your freeCodeCamp account.",
|
||||
"err-2": "You are trying to submit a challenge that does not appear to be a trophy challenge.",
|
||||
"err-3": "It appears that the Microsoft user \"{{msUsername}}\" has not earned this trophy.",
|
||||
"err-4": "Something went wrong trying to verify your trophy. Please check and try again.",
|
||||
"err-3": "We could not get your Microsoft profile from your Microsoft ID.",
|
||||
"err-4": "It appears that the Microsoft user \"{{msUsername}}\" has not earned this trophy.",
|
||||
"err-5": "Something went wrong trying to verify your trophy. Please check and try again.",
|
||||
"verified": "Your trophy from Microsoft's learning platform was verified."
|
||||
}
|
||||
},
|
||||
|
|
|
@ -16,7 +16,8 @@ function Flash({ flashMessage, removeFlashMessage }: FlashProps): JSX.Element {
|
|||
const { type, message, id, variables } = flashMessage;
|
||||
const { t } = useTranslation();
|
||||
|
||||
const flashStyle = type as AlertProps['variant'];
|
||||
const flashStyle =
|
||||
type === 'error' ? 'danger' : (type as AlertProps['variant']);
|
||||
|
||||
function handleClose() {
|
||||
removeFlashMessage();
|
||||
|
|
|
@ -27,10 +27,12 @@ export enum FlashMessages {
|
|||
MsTranscriptLinked = 'flash.ms.transcript.linked',
|
||||
MsTranscriptUnlinked = 'flash.ms.transcript.unlinked',
|
||||
MsTranscriptUnlinkErr = 'flash.ms.transcript.unlink-err',
|
||||
MsProfileErr = 'flash.ms.profile.err',
|
||||
MsTrophyErr1 = 'flash.ms.trophy.err-1',
|
||||
MsTrophyErr2 = 'flash.ms.trophy.err-2',
|
||||
MsTrophyErr3 = 'flash.ms.trophy.err-3',
|
||||
MsTrophyErr4 = 'flash.ms.trophy.err-4',
|
||||
MsTrophyErr5 = 'flash.ms.trophy.err-5',
|
||||
MsTrophyVerified = 'flash.ms.trophy.verified',
|
||||
NameNeeded = 'flash.name-needed',
|
||||
None = '',
|
||||
|
|
|
@ -42,10 +42,12 @@ const toneUrls = {
|
|||
[FlashMessages.MsTranscriptLinked]: CHAL_COMP,
|
||||
[FlashMessages.MsTranscriptUnlinked]: CHAL_COMP,
|
||||
[FlashMessages.MsTranscriptUnlinkErr]: TRY_AGAIN,
|
||||
[FlashMessages.MsProfileErr]: TRY_AGAIN,
|
||||
[FlashMessages.MsTrophyErr1]: TRY_AGAIN,
|
||||
[FlashMessages.MsTrophyErr2]: TRY_AGAIN,
|
||||
[FlashMessages.MsTrophyErr3]: TRY_AGAIN,
|
||||
[FlashMessages.MsTrophyErr4]: TRY_AGAIN,
|
||||
[FlashMessages.MsTrophyErr5]: TRY_AGAIN,
|
||||
[FlashMessages.MsTrophyVerified]: CHAL_COMP,
|
||||
[FlashMessages.NameNeeded]: TRY_AGAIN,
|
||||
// [FlashMessages.None]: '',
|
||||
|
|
Loading…
Reference in New Issue