Unverified Commit e29422fa authored by Yukai Huang's avatar Yukai Huang Committed by GitHub

Merge pull request #1477 from hackmdio/release/2.0.1

Release 2.0.1
parents 16b9409e e07884cc
......@@ -15,6 +15,7 @@ Built on [HackMD](https://hackmd.io) source code, CodiMD lets you host and contr
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# Table of Contents
- [HackMD](#hackmd)
- [CodiMD - The Open Source HackMD](#codimd---the-open-source-hackmd)
- [Documentation](#documentation)
- [Deployment](#deployment)
......@@ -27,14 +28,17 @@ Built on [HackMD](https://hackmd.io) source code, CodiMD lets you host and contr
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## CodiMD - The Open Source HackMD
## HackMD
[HackMD](https://hackmd.io) helps developers write better documents and build active communities with open collaboration.
HackMD is built with one promise - **You own and control all your content**:
- You should be able to easily [download all your online content at once](https://hackmd.io/c/news/%2Fs%2Fr1cx3a3SE).
- Your content formatting should be portable as well. (That's why we choose [markdown](https://hackmd.io/features#Typography).)
- You should be able to control your content's presentation with HTML, [slide mode](https://hackmd.io/p/slide-example), or [book mode](https://hackmd.io/c/book-example/).
With the same promise of you owning your content, CodiMD is the free software version of [HackMD](https://hackmd.io), developed and opened source by the HackMD team with reduced features, so you can use CodiMD for your community and own your data. *(See the [origin of the name CodiMD](https://github.com/hackmdio/hackmd/issues/720).)*
## CodiMD - The Open Source HackMD
CodiMD is the free software version of [HackMD](https://hackmd.io), developed and opened source by the HackMD team with reduced features (without book mode), you can use CodiMD for your community and own all your data. *(See the [origin of the name CodiMD](https://github.com/hackmdio/hackmd/issues/720).)*
CodiMD is perfect for open communities, while HackMD emphasizes on permission and access controls for commercial use cases.
......
......@@ -7,6 +7,7 @@ function parseProfile (data) {
const username = extractProfileAttribute(data, config.oauth2.userProfileUsernameAttr)
const displayName = extractProfileAttribute(data, config.oauth2.userProfileDisplayNameAttr)
const email = extractProfileAttribute(data, config.oauth2.userProfileEmailAttr)
const photo = extractProfileAttribute(data, config.oauth2.userProfilePhotoAttr)
if (!username) {
throw new Error('cannot fetch username: please set correct CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR')
......@@ -16,7 +17,8 @@ function parseProfile (data) {
id: username,
username: username,
displayName: displayName,
email: email
email: email,
photo: photo
}
}
......
......@@ -99,6 +99,7 @@ module.exports = {
userProfileUsernameAttr: 'username',
userProfileDisplayNameAttr: 'displayName',
userProfileEmailAttr: 'email',
userProfilePhotoAttr: 'photo',
scope: 'email'
},
facebook: {
......
......@@ -13,18 +13,32 @@ function getSecret (secret) {
if (fs.existsSync(basePath)) {
module.exports = {
sessionsecret: getSecret('sessionsecret'),
sslkeypath: getSecret('sslkeypath'),
sslcertpath: getSecret('sslcertpath'),
sslcapath: getSecret('sslcapath'),
dhparampath: getSecret('dhparampath'),
dbURL: getSecret('dburl'),
// ssl path
sslKeyPath: getSecret('sslkeypath'),
sslCertPath: getSecret('sslcertpath'),
sslCAPath: getSecret('sslcapath'),
dhParamPath: getSecret('dhparampath'),
// session
sessionSecret: getSecret('sessionsecret'),
imgur: {
clientID: getSecret('imgur_clientid')
},
s3: {
accessKeyId: getSecret('s3_acccessKeyId'),
secretAccessKey: getSecret('s3_secretAccessKey')
},
minio: {
accessKey: getSecret('minio_accessKey'),
secretKey: getSecret('minio_secretKey')
},
azure: {
connectionString: getSecret('azure_connectionString')
},
oauth2: {
clientID: getSecret('oauth2_clientID'),
clientSecret: getSecret('oauth2_clientSecret')
},
facebook: {
clientID: getSecret('facebook_clientID'),
clientSecret: getSecret('facebook_clientSecret')
......@@ -54,6 +68,12 @@ if (fs.existsSync(basePath)) {
clientID: getSecret('google_clientID'),
clientSecret: getSecret('google_clientSecret')
},
imgur: getSecret('imgur_clientid')
ldap: {
bindCredentials: getSecret('ldap_bindCredentials'),
tlsca: getSecret('ldap_tlsca')
},
saml: {
idpCert: getSecret('saml_idpCert')
}
}
}
......@@ -96,7 +96,8 @@ module.exports = {
scope: process.env.CMD_OAUTH2_SCOPE,
userProfileUsernameAttr: process.env.CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR,
userProfileDisplayNameAttr: process.env.CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR,
userProfileEmailAttr: process.env.CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR
userProfileEmailAttr: process.env.CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR,
userProfilePhotoAttr: process.env.CMD_OAUTH2_USER_PROFILE_PHOTO_ATTR
},
dropbox: {
clientID: process.env.CMD_DROPBOX_CLIENTID,
......
......@@ -6,7 +6,7 @@ const config = require('../config')
const { getImageMimeType } = require('../utils')
const logger = require('../logger')
const Minio = require('lib/imageRouter/minio')
const Minio = require('minio')
const minioClient = new Minio.Client({
endPoint: config.minio.endPoint,
port: config.minio.port,
......
......@@ -140,6 +140,10 @@ module.exports = function (sequelize, DataTypes) {
case 'saml':
photo = generateAvatarURL(profile.username, profile.emails[0], bigger)
break
case 'oauth2':
photo = profile.photo
if (!photo) photo = generateAvatarURL(profile.username, profile.email, bigger)
break
}
return photo
}
......
......@@ -34,7 +34,7 @@ async function getNoteById (noteId, { includeUser } = { includeUser: false }) {
}
async function createNote (userId, noteAlias) {
if (!config.allowAnonymous && !!userId) {
if (!config.allowAnonymous && !userId) {
throw new Error('can not create note')
}
......
......@@ -30,11 +30,12 @@ async function checkVersion (ctx) {
const { statusCode, body: data } = await rp({
url: `${VERSION_CHECK_ENDPOINT}?v=${config.version}`,
method: 'GET',
json: true
json: true,
timeout: 3000
})
if (statusCode !== 200 || data.status === 'error') {
logger.error('Version check failed.')
logger.warn('Version check failed.')
return
}
......@@ -46,12 +47,12 @@ async function checkVersion (ctx) {
if (!data.latest) {
const { version, link } = data.versionItem
logger.warn(`Your CodiMD version is out of date! The latest version is ${version}. Please see what's new on ${link}.`)
logger.info(`Your CodiMD version is out of date! The latest version is ${version}. Please see what's new on ${link}.`)
}
} catch (err) {
// ignore and skip version check
logger.error('Version check failed.')
logger.error(err)
logger.warn('Version check failed.')
logger.warn(err)
}
}
......
......@@ -385,12 +385,26 @@
"integrity": "sha512-yuv9BBdA5rk4TpmSrsdNgkLIyRt73hWyBEs7PhWhIozFcNv66JfUzXqA0eT3ToXX0163aVnbpHeJZRvcYy5Seg=="
},
"@hackmd/imgur": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@hackmd/imgur/-/imgur-0.4.1.tgz",
"integrity": "sha512-zvAt/4drM+nZG/yM12hJ7/DtkPffw/fzvr8oDp6twg5a04/HBoGha28vYrZP4fV/a5ZAAnRzxRRbeADxRfsGfA==",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@hackmd/imgur/-/imgur-0.5.0.tgz",
"integrity": "sha512-5WygmZ0LEezFMxlxxuT03Y9ZNtbJU2ECHTi1Mc2m7SPeUG6sfU3vGsQKmooWA6f5F7HLVskuaSVVq9mOMQv5jg==",
"requires": {
"glob": "^7.1.3",
"request": "^2.88.0"
"commander": "^2.13.0",
"glob": "^7.1.2",
"q": "^2.0.3",
"request": "^2.83.0"
},
"dependencies": {
"q": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz",
"integrity": "sha1-dbjbAlWhpa+C9Yw/Oqoe/sfQ0TQ=",
"requires": {
"asap": "^2.0.0",
"pop-iterate": "^1.0.1",
"weak-map": "^1.0.5"
}
}
}
},
"@hackmd/js-sequence-diagrams": {
......@@ -1228,9 +1242,7 @@
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
"dev": true,
"optional": true
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"asn1": {
"version": "0.2.4",
......@@ -11615,6 +11627,11 @@
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
},
"pop-iterate": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pop-iterate/-/pop-iterate-1.0.1.tgz",
"integrity": "sha1-zqz9q0q/NT16DyqqLB/Hs/lBO6M="
},
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
......@@ -16489,6 +16506,11 @@
"typechecker": "^2.0.8"
}
},
"weak-map": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz",
"integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes="
},
"webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
......
{
"name": "codimd",
"version": "2.0.0",
"version": "2.0.1",
"description": "Realtime collaborative markdown notes on all platforms.",
"keywords": [
"Collaborative",
......@@ -33,7 +33,7 @@
"@hackmd/codemirror": "~5.49.5",
"@hackmd/diff-match-patch": "~1.1.3",
"@hackmd/idle-js": "~1.0.1",
"@hackmd/imgur": "~0.4.1",
"@hackmd/imgur": "~0.5.0",
"@hackmd/js-sequence-diagrams": "~0.0.1-alpha.3",
"@hackmd/lz-string": "~1.4.4",
"@hackmd/meta-marked": "~0.4.4",
......
......@@ -108,7 +108,7 @@
}
.ui-toc-label {
opacity: 0.3;
opacity: 0.9;
background-color: #ccc;
border: none;
-webkit-transition: opacity 0.2s; /* Safari */
......@@ -117,13 +117,13 @@
.ui-toc .open .ui-toc-label {
opacity: 1;
color: white;
color: #5f5f5f;
-webkit-transition: opacity 0.2s; /* Safari */
transition: opacity 0.2s;
}
.ui-toc-label:focus {
opacity: 0.3;
opacity: 1;
background-color: #ccc;
color: black;
}
......@@ -326,7 +326,7 @@
margin-left: 10px;
font-size: 12px;
font-weight: 500;
color: #999;
color: rgba(0, 0, 0, 0.85);
}
.expand-toggle:hover, .expand-toggle:focus, .back-to-top:hover, .back-to-top:focus, .go-to-bottom:hover, .go-to-bottom:focus {
......
......@@ -570,7 +570,7 @@ div[contenteditable]:empty:not(:focus):before{
.ui-theme-toggle,
.ui-linter-toggle,
.ui-spellcheck-toggle {
opacity: 0.2;
opacity: 0.5;
cursor: pointer;
}
......
Release Notes
===
<i class="fa fa-tag"></i> 2.0.1 Urocissa caerulea <i class="fa fa-clock-o"></i> 2020-04-09
---
[CodiMD 2.0.1](https://github.com/hackmdio/codimd/releases/tag/2.0.1) is a minor release fixing bugs introduced in 2.0.0 and earlier versions along with some enhancements. We encourage everyone to upgrade to 2.0.1 now. See how things are going on [GitHub](https://github.com/hackmdio/codimd/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc+milestone%3ANext). Stay tuned and healthy, and we hope you love it!
### Enhancements
- Allow inline markdown in spoiler summary syntax
- Improve visibility of some UI elements
- Support avatar for OAuth users
### Fixes
- Fix to add missing configs in docker secret
- Fix not able to upload image using imgur
- Fix to improve version checker behavior
- Fix Wikipedia link in 2.0.0 release notes
- Fix require path for minio
- Fix check for creating free url notes
[Check out the complete release note][v2_0_1]. Thank you CodiMD community and all our contributors. ❤️
[v2_0_1]: https://hackmd.io/@codimd/release-notes/%2F%40codimd%2Fv2_0_1
<i class="fa fa-tag"></i> 2.0.0 Urocissa caerulea <i class="fa fa-clock-o"></i> 2020-03-02
---
......@@ -11,7 +36,7 @@ Release Notes
> The Taiwan blue magpie (Urocissa caerulea), also called the Taiwan magpie, Formosan blue magpie , or the "long-tailed mountain lady", is a species of bird of the crow family. It is endemic to Taiwan.
>
> \- Wikipedia [Taiwan blue magpie](en.wikipedia.org/wiki/Taiwan_blue_magpie)
> \- Wikipedia [Taiwan blue magpie](https://en.wikipedia.org/wiki/Taiwan_blue_magpie)
In the past few months, we delivered not only a bunch of awesome features but also some critical bug fixes. Moreover, we refactored CodiMD's backend and started to write new tests.
......
......@@ -1124,7 +1124,7 @@ md.use(markdownitContainer, 'spoiler', {
// opening tag
const summary = m[1] && m[1].trim()
if (summary) {
return `<details><summary>${md.utils.escapeHtml(summary)}</summary>\n`
return `<details><summary>${md.renderInline(summary)}</summary>\n`
} else {
return `<details>\n`
}
......
......@@ -125,7 +125,7 @@ md.use(markdownitContainer, 'spoiler', {
const partClass = `class="part raw" data-startline="${startline}" data-endline="${endline}"`
const summary = m[1] && m[1].trim()
if (summary) {
return `<details ${partClass}><summary>${md.utils.escapeHtml(summary)}</summary>\n`
return `<details ${partClass}><summary>${md.renderInline(summary)}</summary>\n`
} else {
return `<details ${partClass}>\n`
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment