Merge branch 'master' into reject-username

This commit is contained in:
Kim Gardner
2018-05-25 14:16:02 -04:00
committed by GitHub
12 changed files with 100 additions and 39 deletions
+2 -1
View File
@@ -7,6 +7,7 @@ ONBUILD ARG TALK_REPLY_COMMENTS_LOAD_DEPTH=3
ONBUILD ARG TALK_THREADING_LEVEL=3
ONBUILD ARG TALK_DEFAULT_STREAM_TAB=all
ONBUILD ARG TALK_DEFAULT_LANG=en
ONBUILD ARG TALK_WHITELISTED_LANGUAGES
ONBUILD ARG TALK_PLUGINS_JSON
ONBUILD ARG TALK_WEBPACK_SOURCE_MAP
@@ -20,4 +21,4 @@ ONBUILD COPY . /usr/src/app
ONBUILD RUN cli plugins reconcile && \
yarn && \
yarn build && \
yarn cache clean
yarn cache clean
@@ -1,5 +1,4 @@
@custom-media --big-viewport (min-width: 780px);
.root {
border-bottom: 1px solid #e0e0e0;
font-size: 18px;
@@ -13,7 +12,6 @@
margin-top: 13px;
min-height: 0;
outline: 0;
/*
Fix rendering issues in Safari by promoting this
into its own layer.
@@ -21,7 +19,6 @@
https://www.pivotaltracker.com/story/show/151142211
*/
transform: translateZ(0);
&:last-child {
border-bottom: none;
}
@@ -39,7 +36,6 @@
display: flex;
align-items: center;
justify-content: space-between;
}
.author {
@@ -74,7 +70,7 @@
max-width: 500px;
font-weight: 300;
font-size: 16px;
word-break: break-all;
overflow-wrap: break-word;
}
.created {
@@ -95,7 +91,6 @@
font-weight: 500;
line-height: 1.2;
max-width: 500px;
a {
display: inline-block;
color: #063b9a;
@@ -103,17 +98,15 @@
font-weight: 500;
letter-spacing: .5px;
margin-left: 10px;
font-size: 13px;
margin-left: 5px;
padding-bottom: 0px;
border-bottom: solid 1px;
line-height: 16px;
&:hover {
opacity: .9;
cursor: pointer;
}
}
}
}
@@ -138,12 +131,10 @@
cursor: pointer;
font-weight: normal;
white-space: nowrap;
&:hover {
text-decoration: underline;
opacity: .9;
}
i {
font-size: 12px;
position: relative;
@@ -172,7 +163,6 @@
align-items: center;
justify-content: flex-end;
margin-right: 14px;
i {
margin-right: 5px;
}
@@ -181,7 +171,6 @@
@media (--big-viewport) {
.root {
margin-bottom: 30px;
&:last-child {
border-bottom: 1px solid #e0e0e0;
}
@@ -190,7 +179,6 @@
.commentContent {
display: flex;
blockquote {
font-size: inherit;
line-height: inherit;
+22 -5
View File
@@ -39,7 +39,20 @@ import pt_BR from '../../../locales/pt_BR.yml';
import zh_CN from '../../../locales/zh_CN.yml';
import zh_TW from '../../../locales/zh_TW.yml';
export const defaultLocale = process.env.TALK_DEFAULT_LANG.replace(/-/g, '_');
// the list of languages that are whitelisted. If false, all languages that are
// supported by Talk will be enabled.
const whitelistedLanguages =
process.env.TALK_WHITELISTED_LANGUAGES &&
process.env.TALK_WHITELISTED_LANGUAGES.split(',').map(l => l.trim());
// The default language. If the whitelisted languages is specified and the
// default language is not in that list, then the first language in the
// whitelisted list will be used as the default.
export const defaultLocale = whitelistedLanguages
? !whitelistedLanguages.includes(process.env.TALK_DEFAULT_LANG)
? whitelistedLanguages[0]
: process.env.TALK_DEFAULT_LANG
: process.env.TALK_DEFAULT_LANG;
export const translations = {
...ar,
@@ -64,10 +77,14 @@ let TIMEAGO_INSTANCE;
// to the default language.
const detectLanguage = () =>
first(
negotiateLanguages(navigator.languages, supportedLocales, {
defaultLocale,
strategy: 'lookup',
})
negotiateLanguages(
navigator.languages,
whitelistedLanguages || supportedLocales,
{
defaultLocale,
strategy: 'lookup',
}
)
);
export function setupTranslations() {
+18
View File
@@ -36,6 +36,13 @@ const CONFIG = {
// rendered text.
DEFAULT_LANG: process.env.TALK_DEFAULT_LANG || 'en',
// WHITELISTED_LANGUAGES is a comma separated list of language/locales that
// should be supported. If the default language is not included in the
// whitelist list, the first entry will be used as the default.
WHITELISTED_LANGUAGES:
process.env.TALK_WHITELISTED_LANGUAGES &&
process.env.TALK_WHITELISTED_LANGUAGES.split(',').map(l => l.trim()),
// When TRUE, it ensures that database indexes created in core will not add
// indexes.
CREATE_MONGO_INDEXES: process.env.DISABLE_CREATE_MONGO_INDEXES !== 'TRUE',
@@ -317,6 +324,17 @@ CONFIG.JWT_COOKIE_NAMES = uniq(
])
);
//------------------------------------------------------------------------------
// Locale validation
//------------------------------------------------------------------------------
if (
CONFIG.WHITELISTED_LANGUAGES &&
!CONFIG.WHITELISTED_LANGUAGES.includes(CONFIG.DEFAULT_LANG)
) {
CONFIG.DEFAULT_LANG = CONFIG.WHITELISTED_LANGUAGES[0];
}
//------------------------------------------------------------------------------
// External database url's
//------------------------------------------------------------------------------
+1 -1
View File
@@ -81,4 +81,4 @@ TALK_JWT_SECRET=jX9y8G2ApcVLwyL{$6s3
Be default, we sign our tokens with HMAC using a SHA-256 hash algorithm. If you
want to change the signing algorithm, or use multiple signing/verifying keys,
refer to our [Advanced Configuration](/talk/advanced-configuration/) documentation.
refer to our [Advanced Configuration](/talk/advanced-configuration/#talk-jwt-secret) documentation.
@@ -31,6 +31,21 @@ image you can specify it with `--build-arg TALK_DEFAULT_LANG=en`.
Specify the default translation language. (Default `en`)
## TALK_WHITELISTED_LANGUAGES
This is a **Build Variable** and must be consumed during build. If using the
[Docker-onbuild](/talk/installation-from-docker/#onbuild)
image you can specify it with `--build-arg TALK_WHITELISTED_LANGUAGES=en`.
Specify the comma separated whitelisted languages that you want the Talk
application to serve. This will override the available set of languages that
Talk will allow to be served.
If the [TALK_DEFAULT_LANG](#talk-default-lang) is not included in this list of
whitelisted languages, then the first whitelisted language will become the
default language. If this parameter is empty, then all languages supported by
Talk will be whitelisted. (Default '')
## TALK_DEFAULT_STREAM_TAB
This is a **Build Variable** and must be consumed during build. If using the
+23 -8
View File
@@ -25,9 +25,10 @@ state (you don't use the auth anywhere else now). A great example of this is our
You can integrate Talk with any authentication service to enable single sign-on
for users. The steps to do that are:
1. Create a service that generates [JWT tokens](https://jwt.io).
1. Create a service that generates [JWT tokens](https://jwt.io/introduction/).
2. Push the token into the embed.
3. Implement the `tokenUserNotFound` hook to process the token.
3. Implement the [`tokenUserNotFound`](#implement-tokenusernotfound) hook to
process the token.
### Create JWT Token
@@ -39,7 +40,20 @@ Using that demo application, you'll see how you can:
1. Create a node application that can issue JWT's that are compatible with Talk.
2. Provide a validation endpoint that can be used by Talk to validate the token
and get the user via the `tokenUserNotFound` hook.
and get the user via the [`tokenUserNotFound`](#implement-tokenusernotfound)
hook.
It's also important to note a few requirements for proper integration with Talk.
The generated JWT must contain the following claims:
- [`jti`](https://tools.ietf.org/html/rfc7519#section-4.1.7): a unique identifier for the token (like a uuid/v4)
- [`exp`](https://tools.ietf.org/html/rfc7519#section-4.1.4): the expiry date of the token as a unix timestamp
- [`sub`](https://tools.ietf.org/html/rfc7519#section-4.1.2): the user identifier that can be used to lookup the user in the mongo
database
- The user may not yet exist in the database, but that's the responsibility
of the [`tokenUserNotFound`](#implement-tokenusernotfound) hook.
- [`iss`](https://tools.ietf.org/html/rfc7519#section-4.1.1): the issuer for the token must match the value of `TALK_JWT_ISSUER`
- [`aud`](https://tools.ietf.org/html/rfc7519#section-4.1.3): the audience for the token must match the value of `TALK_JWT_AUDIENCE`
### Push token into embed
@@ -47,7 +61,8 @@ We're assuming that your CMS is capable of authenticating a user account, or
at least having the user's details available to send off to the token creation
service we created/used in the previous step.
Using the token that was created for the user, you simply have to ammend the template where Talk is rendering to read as the following:
Using the token that was created for the user, you simply have to amend the
template where Talk is rendering to read as the following:
```js
Coral.Talk.render(document.getElementById('coralStreamEmbed'), {
@@ -72,12 +87,12 @@ example issuer and Talk must match:
| Talk | Token Issuer Example |
|------|----------------------|
|`JWT_ISSUER`|`JWT_ISSUER`|
|`JWT_AUDIENCE`|`JWT_AUDIENCE`|
|`SECRET`|`JWT_SECRET`*|
|[`TALK_JWT_ISSUER`](/talk/advanced-configuration/#talk-jwt-issuer)|`JWT_ISSUER`|
|[`TALK_JWT_AUDIENCE`](/talk/advanced-configuration/#talk-jwt-audience)|`JWT_AUDIENCE`|
|[`TALK_JWT_SECRET`](/talk/advanced-configuration/#talk-jwt-secret)|`JWT_SECRET`*|
\* Note that secrets is a pretty complex topic, refer to the
[TALK-JWT-SECRET](/talk/advanced-configuration/#TALK-JWT-SECRET) configuration
[TALK_JWT_SECRET](/talk/advanced-configuration/#talk-jwt-secret) configuration
reference, the basic takeaway is that the secret used to sign the tokens issued
by the issuer must be able to be verified by Talk.
+2 -3
View File
@@ -291,11 +291,10 @@ pre {
.content {
article {
p a:not(.plain-link) {
@extend .coral-link;
}
p a:not(.plain-link),
ul:not(.toc__menu) li a,
ol li a,
td a,
dd > a {
@extend .coral-link;
}
@@ -58,7 +58,7 @@
display: flex;
flex-direction: column;
align-items: center;
}
}
}
.title {
@@ -97,6 +97,7 @@
color: #3B4A53;
font-size: 1em;
margin-bottom: 15px;
opacity: 1;
}
.block {
@@ -24,6 +24,8 @@
box-sizing: border-box;
margin: 0;
padding: 0;
top: calc(50% - 2px);
left: 0;
}
.container {
@@ -33,4 +35,4 @@
align-items: center;
height: 50px;
margin: 0 20px;
}
}
+9 -5
View File
@@ -8,7 +8,7 @@ const {
const { first, get, has, merge, isUndefined } = require('lodash');
const yaml = require('yamljs');
const plugins = require('./plugins');
const { DEFAULT_LANG } = require('../config');
const { DEFAULT_LANG, WHITELISTED_LANGUAGES } = require('../config');
const resolve = (...paths) =>
path.resolve(path.join(__dirname, '..', 'locales', ...paths));
@@ -105,10 +105,14 @@ const i18n = {
// negotiate the language.
const lang = first(
negotiateLanguages(acceptsLanguages, supportedLocales, {
defaultLocale: DEFAULT_LANG,
strategy: 'lookup',
})
negotiateLanguages(
acceptsLanguages,
WHITELISTED_LANGUAGES || supportedLocales,
{
defaultLocale: DEFAULT_LANG,
strategy: 'lookup',
}
)
);
debug(`decided language as '${lang}'`);
+1
View File
@@ -169,6 +169,7 @@ const config = {
TALK_REPLY_COMMENTS_LOAD_DEPTH: '3',
TALK_DEFAULT_STREAM_TAB: 'all',
TALK_DEFAULT_LANG: 'en',
TALK_WHITELISTED_LANGUAGES: '',
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),