Feature(challenges): add code-uri utils
Fix(nav): points nav item propTypes
This commit is contained in:
64
client/utils/code-uri.js
Normal file
64
client/utils/code-uri.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import flow from 'lodash/flow';
|
||||||
|
import { decodeFcc } from '../../common/utils/encode-decode';
|
||||||
|
|
||||||
|
const queryRegex = /^(\?|#\?)/;
|
||||||
|
export function legacyIsInQuery(query, decode) {
|
||||||
|
let decoded;
|
||||||
|
try {
|
||||||
|
decoded = decode(query);
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!decoded || typeof decoded.split !== 'function') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return decoded
|
||||||
|
.replace(queryRegex, '')
|
||||||
|
.split('&')
|
||||||
|
.reduce(function(found, param) {
|
||||||
|
var key = param.split('=')[0];
|
||||||
|
if (key === 'solution') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getKeyInQuery(query, keyToFind = '') {
|
||||||
|
return query
|
||||||
|
.split('&')
|
||||||
|
.reduce((oldValue, param) => {
|
||||||
|
const key = param.split('=')[0];
|
||||||
|
const value = param
|
||||||
|
.split('=')
|
||||||
|
.slice(1)
|
||||||
|
.join('=');
|
||||||
|
|
||||||
|
if (key === keyToFind) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return oldValue;
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLegacySolutionFromQuery(query = '', decode) {
|
||||||
|
return flow(
|
||||||
|
getKeyInQuery,
|
||||||
|
decode,
|
||||||
|
decodeFcc
|
||||||
|
)(query, 'solution');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCodeUri({ location, decodeURIComponent }) {
|
||||||
|
let query;
|
||||||
|
if (
|
||||||
|
location.search &&
|
||||||
|
legacyIsInQuery(location.search, decodeURIComponent)
|
||||||
|
) {
|
||||||
|
query = location.search.replace(/^\?/, '');
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getLegacySolutionFromQuery(query, decodeURIComponent);
|
||||||
|
}
|
@ -7,8 +7,8 @@ export default React.createClass({
|
|||||||
'aria-controls': React.PropTypes.string,
|
'aria-controls': React.PropTypes.string,
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
href: React.PropTypes.string,
|
href: React.PropTypes.string,
|
||||||
onClick: React.PropTypes.func.isRequired,
|
onClick: React.PropTypes.func,
|
||||||
points: React.PropTypes.func,
|
points: React.PropTypes.number,
|
||||||
title: React.PropTypes.node
|
title: React.PropTypes.node
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,42 +1,17 @@
|
|||||||
import { compose } from 'redux';
|
import flow from 'lodash/flow';
|
||||||
import { bonfire, html, js } from '../../utils/challengeTypes';
|
import { bonfire, html, js } from '../../utils/challengeTypes';
|
||||||
|
import { decodeScriptTags } from '../../../utils/encode-decode';
|
||||||
import protect from '../../utils/empty-protector';
|
import protect from '../../utils/empty-protector';
|
||||||
|
|
||||||
export function encodeScriptTags(value) {
|
|
||||||
return value
|
|
||||||
.replace(/<script>/gi, 'fccss')
|
|
||||||
.replace(/<\/script>/gi, 'fcces');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function decodeSafeTags(value) {
|
|
||||||
return value
|
|
||||||
.replace(/fccss/gi, '<script>')
|
|
||||||
.replace(/fcces/gi, '</script>');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function encodeFormAction(value) {
|
|
||||||
return value.replace(
|
|
||||||
/<form[^>]*>/,
|
|
||||||
val => val.replace(/action(\s*?)=/, 'fccfaa$1=')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function decodeFccfaaAttr(value) {
|
|
||||||
return value.replace(
|
|
||||||
/<form[^>]*>/,
|
|
||||||
val => val.replace(/fccfaa(\s*?)=/, 'action$1=')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function arrayToString(seedData = ['']) {
|
export function arrayToString(seedData = ['']) {
|
||||||
seedData = Array.isArray(seedData) ? seedData : [seedData];
|
seedData = Array.isArray(seedData) ? seedData : [seedData];
|
||||||
return seedData.reduce((seed, line) => '' + seed + line + '\n', '\n');
|
return seedData.reduce((seed, line) => '' + seed + line + '\n', '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildSeed({ challengeSeed = [] } = {}) {
|
export function buildSeed({ challengeSeed = [] } = {}) {
|
||||||
return compose(
|
return flow(
|
||||||
decodeSafeTags,
|
arrayToString,
|
||||||
arrayToString
|
decodeScriptTags
|
||||||
)(challengeSeed);
|
)(challengeSeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
common/utils/encode-decode.js
Normal file
46
common/utils/encode-decode.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import flow from 'lodash/flow';
|
||||||
|
|
||||||
|
// we don't store loop protect disable key
|
||||||
|
export function removeNoprotect(val) {
|
||||||
|
return val.replace(/noprotect/gi, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encodeScriptTags(val) {
|
||||||
|
return val
|
||||||
|
.replace(/<script>/gi, 'fccss')
|
||||||
|
.replace(/<\/script>/gi, 'fcces');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decodeScriptTags(val) {
|
||||||
|
return val
|
||||||
|
.replace(/fccss/gi, '<script>')
|
||||||
|
.replace(/fcces/gi, '</script>');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encodeFormAction(val) {
|
||||||
|
return val.replace(
|
||||||
|
// look for attributes in a form
|
||||||
|
/<form[^>]*>/,
|
||||||
|
// val is the string within the opening form tag
|
||||||
|
// look for an `action` attribute, replace it with a fcc tag
|
||||||
|
val => val.replace(/action(\s*?)=/, 'fccfaa$1=')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decodeFormAction(val) {
|
||||||
|
return val.replace(
|
||||||
|
/<form[^>]*>/,
|
||||||
|
val => val.replace(/fccfaa(\s*?)=/, 'action$1=')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const encodeFcc = flow([
|
||||||
|
removeNoprotect,
|
||||||
|
encodeFormAction,
|
||||||
|
encodeScriptTags
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const decodeFcc = flow([
|
||||||
|
decodeFormAction,
|
||||||
|
decodeScriptTags
|
||||||
|
]);
|
Reference in New Issue
Block a user