link fe: use base64url for encoding URLs

base64 is not actually url-safe, since it includes / (and +). This
includes a simple hand-rolled base64url implementation, and uses that
instead.
This commit is contained in:
Fang 2020-02-07 00:18:52 +01:00
parent b0759ad8bc
commit e5337c99c7
No known key found for this signature in database
GPG Key ID: EB035760C1BBA972
5 changed files with 27 additions and 5 deletions

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react';
import { Route, Link } from 'react-router-dom';
import { base64urlEncode } from '../../lib/util';
export class CommentsPagination extends Component {
render() {
@ -16,7 +17,7 @@ export class CommentsPagination extends Component {
? "dib"
: "dn";
let encodedUrl = window.btoa(props.url);
let encodedUrl = base64urlEncode(props.url);
let popout = (props.popout) ? "/popout" : "";
return (

View File

@ -3,6 +3,7 @@ import moment from 'moment';
import { Sigil } from '/components/lib/icons/sigil';
import { Route, Link } from 'react-router-dom';
import { base64urlEncode } from '../../lib/util';
export class LinkItem extends Component {
constructor(props) {
@ -45,7 +46,7 @@ export class LinkItem extends Component {
hostname = hostname[4];
}
let encodedUrl = window.btoa(props.url);
let encodedUrl = base64urlEncode(props.url);
let comments = props.comments + " comment" + ((props.comments === 1) ? "" : "s");

View File

@ -7,6 +7,7 @@ import { Sigil } from '/components/lib/icons/sigil';
import { Comments } from './lib/comments';
import { uxToHex } from '../lib/util';
import moment from 'moment'
import { base64urlEncode } from '../lib/util';
export class LinkDetail extends Component {
constructor(props) {
@ -81,7 +82,7 @@ export class LinkDetail extends Component {
render() {
let props = this.props;
let popout = (props.popout) ? "/popout" : "";
let routePath = props.path + "/" + props.page + "/" + props.linkIndex + "/" + window.btoa(props.url);
let routePath = props.path + "/" + props.page + "/" + props.linkIndex + "/" + base64urlEncode(props.url);
const data = this.state.data || props.data;
let ship = data.ship || "zod";
@ -160,7 +161,7 @@ export class LinkDetail extends Component {
<span className="f9 inter gray2 pr3 v-mid">
{this.state.timeSinceLinkPost}
</span>
<Link to={"/~link" + props.path + "/" + props.page + "/" + props.linkIndex + "/" + window.btoa(props.url)} className="v-top">
<Link to={"/~link" + props.path + "/" + props.page + "/" + props.linkIndex + "/" + base64urlEncode(props.url)} className="v-top">
<span className="f9 inter gray2">
{comments}
</span>

View File

@ -9,6 +9,7 @@ import { store } from '/store';
import { Skeleton } from '/components/skeleton';
import { Links } from '/components/links-list';
import { LinkDetail } from '/components/link';
import { base64urlDecode } from '../lib/util';
export class Root extends Component {
@ -110,7 +111,7 @@ export class Root extends Component {
let index = props.match.params.index || 0;
let page = props.match.params.page || 0;
let url = window.atob(props.match.params.encodedUrl);
let url = base64urlDecode(props.match.params.encodedUrl);
let data = !!links[groupPath]
? !!links[groupPath][page]

View File

@ -14,6 +14,24 @@ export function uuid() {
return str.slice(0,-1);
}
// encodes string into base64url,
// by encoding into base64 and replacing non-url-safe characters.
//
export function base64urlEncode(string) {
return window.btoa(string)
.split('+').join('-')
.split('/').join('_');
}
// decode base64url. inverse of base64urlEncode above.
//
export function base64urlDecode(string) {
return window.atob(
string.split('_').join('/')
.split('-').join('+')
);
}
export function isPatTa(str) {
const r = /^[a-z,0-9,\-,\.,_,~]+$/.exec(str)
return !!r;