Skip to content

Commit

Permalink
Merge pull request #239 from thematters/develop
Browse files Browse the repository at this point in the history
Release: v1.0.1
  • Loading branch information
devformatters authored Mar 21, 2019
2 parents 7cd7705 + 8f90244 commit 5d1892c
Show file tree
Hide file tree
Showing 31 changed files with 430 additions and 72 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.1] - 2019-03-21
### Added
* `User.status.role` #230
* Invitation related notices #234

### Changed
* Make state of newly registered user as onboarding #229 #237
* Fix email reseting content has no user data #232
* Fix duplication issue in tags, authors and hottest articles #233
* Fix bug with word count #233
* Prioritize viewer language setting over header #233
* Optimize summary generation #233
* Strip html tag and redundant spaces in content #235
* Check permission if viewer request to edit comment #238
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "matters-server",
"version": "0.0.1",
"version": "1.0.1",
"description": "Matters Server",
"main": "build/index.js",
"engines": {
Expand Down
6 changes: 6 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,11 @@ input UserRegisterInput {
codeId: ID!
}

enum UserRole {
user
admin
}

type UserSettings {
"""User language setting"""
language: UserLanguage!
Expand All @@ -1247,6 +1252,7 @@ enum UserState {

type UserStatus {
state: UserState!
role: UserRole!

"""Total MAT left in wallet"""
MAT: MAT!
Expand Down
5 changes: 5 additions & 0 deletions src/common/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ export const EMAIL_TEMPLATE_ID = {
zh_hant: 'd-daaa0da594034f509cfa01e5ecdb1f77',
zh_hans: 'd-1256cd9153204e6c840c2e51eb326f63',
en: 'd-daaa0da594034f509cfa01e5ecdb1f77'
},
userActivated: {
zh_hant: 'd-6e0a8f374ed04b068baabaf2db65b945',
zh_hans: 'd-b2758620963644ff88f6ec834cb67275',
en: 'd-6e0a8f374ed04b068baabaf2db65b945'
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/common/utils/getViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ export const getViewerFromReq = async ({
}
const userDB = await userService.baseFindByUUID(decoded.uuid)

// overwrite user setting by request
// overwrite request by user settings
if (isWeb) {
user = { ...userDB, ip: user.ip }
user = { ip: user.ip, ...userDB }
} else {
user = { ...userDB, ...user }
user = { ...user, ...userDB }
}
} catch (err) {
logger.info('token invalid')
Expand Down
46 changes: 33 additions & 13 deletions src/common/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,39 @@ export * from './cookie'
export * from './removeEmpty'
export * from './xss'

export const stripHtml = (html: string) =>
(html || '').replace(/(<([^>]+)>)/gi, '')

export const countWords = (html: string) =>
stripHtml(html)
.split(' ')
.filter(s => s !== '').length

export const makeSummary = (string: string, length?: number) =>
_.truncate(string, {
length: length || 200,
separator: /,? +/
})
export const stripHtml = (html: string, replacement = ' ') =>
(html || '').replace(/((<([^>]+)>)|&nbsp;)/gi, replacement)

export const countWords = (html: string) => {
const matches = stripHtml(html).match(/[\u4e00-\u9fcc]|\S+/g)

return matches ? matches.length : 0
}

export const makeSummary = (html: string, length = 140) => {
// buffer for search
const buffer = 20

// split on sentence breaks
const sections = stripHtml(html, '')
.replace(/([.?!。?!”])\s*/g, '$1|')
.split('|')

// grow summary within buffer
let summary = ''
while (summary.length < length - buffer && sections.length > 0) {
const el = sections.shift() || ''

const addition =
el.length + summary.length > length + buffer
? `${el.substring(0, length - summary.length)}...`
: el

summary = summary.concat(addition)
}

return summary
}

/**
* Make a valid user name based on a given email address. It removes all special characters including _.
Expand Down
13 changes: 13 additions & 0 deletions src/common/utils/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ export const isValidPassword = (password: string): boolean => {
return /^[a-zA-Z0-9]*$/.test(password)
}

/**
* Validate user raw pass word. It must has at least one alphabet, one
* number and minimum length should be 8.
*
* @see https://mattersnews.slack.com/archives/G8877EQMS/p1546446430005500
*/
export const isValidStrictPassword = (password: string): boolean => {
if (!password || password.length < 8) {
return false
}
return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/.test(password)
}

/**
* Validate if string is in english.
*/
Expand Down
6 changes: 4 additions & 2 deletions src/connectors/__test__/notificationService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ describe('user notify setting', async () => {
'comment_banned',
'article_banned',
'comment_reported',
'article_reported'
'article_reported',
'user_activated'
]
const defaultNoifySetting: { [key in NotificationType]: boolean } = {
user_new_follower: true,
Expand All @@ -62,7 +63,8 @@ describe('user notify setting', async () => {
comment_banned: false,
article_banned: false,
comment_reported: false,
article_reported: false
article_reported: false,
user_activated: true
}

test('user receives notifications', async () => {
Expand Down
4 changes: 3 additions & 1 deletion src/connectors/articleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class ArticleService extends BaseService {
// prepare metadata
const author = await userService.dataloader.load(authorId)
const now = new Date()
const summary = draftSummary || makeSummary(stripHtml(content))
const summary = draftSummary || makeSummary(content)
const userImg =
author.avatar && (await systemService.findAssetUrl(author.avatar))
const articleImg = cover && (await systemService.findAssetUrl(cover))
Expand Down Expand Up @@ -314,6 +314,7 @@ export class ArticleService extends BaseService {
)
.leftJoin('article', 'view.id', 'article.id')
.orderByRaw('latest_activity DESC NULLS LAST')
.orderBy('view.id', 'desc')
.where({ 'article.state': ARTICLE_STATE.active, ...where })
.limit(limit)
.offset(offset)
Expand Down Expand Up @@ -412,6 +413,7 @@ export class ArticleService extends BaseService {
.select('view.*', 'article.state', 'article.public')
.join('article', 'view.id', 'article.id')
.orderByRaw('topic_score DESC NULLS LAST')
.orderBy('view.id', 'desc')
.where({ 'article.state': ARTICLE_STATE.active, ...where })
.limit(limit)
.offset(offset)
Expand Down
22 changes: 17 additions & 5 deletions src/connectors/mail/templates/invitationSuccess.mjml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<mj-body mj-class="body">
<mj-text mj-class="preheader" css-class="preheader">
你已成為 Matters 內容平台的創作者,已幫你解鎖全部创作功能
你已成為 Matters 內容平台的創作者,已幫你解鎖全部創作功能
</mj-text>

<mj-wrapper mj-class="wrapper">
Expand All @@ -17,10 +17,18 @@
<mj-include path="./partials/greeting.mjml" />

<mj-text padding-top="16px">
{{#if sender.displayName}}
你的朋友 <a href="https://matters.news/@{{sender.userName}}" class="link">{{sender.displayName}}</a> 邀請你成為 Matters 內容平台的創作者,已幫你解鎖全部创作功能。
{{#if invitation}}
{{#if sender.displayName}}
你的好友 <a href="https://matters.news/@{{sender.userName}}" class="link">{{sender.displayName}}</a> 邀請你成為 Matters 內容社群的創作者,完成註冊並解鎖全部創作功能。
{{else}}
你已成為 Matters 內容平台的創作者,完成註冊並解鎖全部創作功能。
{{/if}}
{{else}}
Matty 邀請你成為 Matters 內容平台的創作者,已幫你解鎖全部创作功能。
{{#if sender.displayName}}
你的好友 <a href="https://matters.news/@{{sender.userName}}" class="link">{{sender.displayName}}</a> 邀請你成為 Matters 內容社群的創作者,已幫你解鎖全部創作功能。
{{else}}
你已成為 Matters 內容社群的創作者,已幫你解鎖全部創作功能。
{{/if}}
{{/if}}
</mj-text>

Expand All @@ -33,7 +41,11 @@
</mj-button>

<mj-text padding-top="32px">
你在 Matters 發布的文章將通過星際文件系統(InterPlanetary File System, IPFS)實現分佈式存儲。文章可以永久保存,也可以通過多個分佈式節點傳播,不再侷限於單一網頁地址訪問。瀏覽<a class="link" target="_blank" href="https://matters.news/forum/?post=53ae62fa-2a1a-419d-bc77-d744f13ffd3d">產品公告</a>可了解具體操作方法。
你在 Matters 發布的文章將通過星際文件系統(InterPlanetary File System,IPFS)實現分佈式存儲。文章可以永久保存,也可以通過多個分佈式節點傳播,不再侷限於單一網頁地址訪問。瀏覽<a class="link" href="https://matters.news/faq">常見問題</a>可了解更多玩法。
</mj-text>

<mj-text padding-top="16px">
Matters 會第一時間在<a class="link" href="https://www.facebook.com/MattersLab2018">臉書</a>和<a class="link" href="https://weibo.com/6695370718/profile?topnav=1&wvr=6">微博帳號 MattersLab</a> 與大家分享新動態,歡迎關注。
</mj-text>

<mj-include path="./partials/ending.mjml" />
Expand Down
12 changes: 8 additions & 4 deletions src/connectors/mail/templates/registerSuccess.mjml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@
<mj-include path="./partials/greeting.mjml" />

<mj-text padding-top="16px">
恭喜你,你已經成功註冊了 Matters 賬號,歡迎 <a class="link" href="https://matters.news">浏览社区里的精彩内容 →</a>
恭喜你,你已成功註冊 Matters 帳號,歡迎<a class="link" href="https://matters.news/">瀏覽站上精彩內容 →</a>
</mj-text>

<mj-text padding-top="16px">
目前 Matters 是一個邀請制社區,你的賬號需要激活才能擁有創作資格,你可以向你認識的老用戶索取激活資格。
由於 Matters 目前處於邀請制階段,你的帳號尚需要獲得老用戶激活,才能解鎖全部的創作功能。你可以透過各種社交工具尋找你可能認識的 Matters 老用戶(加入<a class="link" href="https://t.me/joinchat/BXzlWUhXaWNZ-TXJZJCzDQ">官方 Telegram 群組</a>尋找老用戶),也可以關注 <a class="link" href="https://www.facebook.com/MattersLab2018">Matters 臉書</a>和<a class="link" href="https://weibo.com/6695370718/profile?topnav=1&wvr=6">微博帳號 MattersLab</a>,即時了解激活權限新玩法。
</mj-text>

<mj-text padding-top="16px">
若有更多問題,可以透過 email 聯絡我們:[email protected]
</mj-text>
</mj-column>
</mj-section>

<mj-section mj-class="card" padding-top="24px" padding-bottom="0">
<!-- <mj-section mj-class="card" padding-top="24px" padding-bottom="0">
<mj-include path="./partials/download.mjml" />
</mj-section>
</mj-section> -->

<mj-section mj-class="card" padding-top="0">
<mj-column>
Expand Down
38 changes: 38 additions & 0 deletions src/connectors/mail/templates/userActivated.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<mjml>
<mj-head>
<mj-include path="./partials/head.mjml" />
<mj-title>Matters | 你邀請的好友已進站</mj-title>
</mj-head>

<mj-body mj-class="body">
<mj-wrapper mj-class="wrapper">
<mj-include path="./partials/header.mjml" />

<mj-section mj-class="card">
<mj-column>
<mj-include path="./partials/greeting.mjml" />

<mj-text padding-top="16px">
恭喜你,你的好友 {{ email }} 已透過你的邀請註冊成功,並開啟了創作者資格。感謝你們一起搭建 Matters 社群,5 MAT 獎勵已送達。
</mj-text>

<mj-button mj-class="cta-button" href="https://matters.news/@{{ userName }}">
查看好友 →
</mj-button>

<mj-text padding-top="32px">
期待你持續在 Matters 上發佈文章、收穫 MAT,獲取邀請資格,為我們介紹更多新朋友。
</mj-text>

<mj-text padding-top="16px">
Matters 會第一時間在<a class="link" href="https://www.facebook.com/MattersLab2018">臉書</a>和<a class="link" href="https://weibo.com/6695370718/profile?topnav=1&wvr=6">微博帳號 MattersLab</a> 與大家分享新動態,歡迎關注。
</mj-text>

<mj-include path="./partials/ending.mjml" />
</mj-column>
</mj-section>

<mj-include path="./partials/footer.mjml" />
</mj-wrapper>
</mj-body>
</mjml>
44 changes: 40 additions & 4 deletions src/connectors/notificationService/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logger from 'common/logger'
import { NotificationPrarms, PutNoticeParams, LANGUAGES } from 'definitions'
import { toGlobalId } from 'common/utils'
import { USER_ROLE } from 'common/enums'
import { BaseService } from 'connectors/baseService'

import { mail } from './mail'
Expand All @@ -24,10 +25,10 @@ export class NotificationService extends BaseService {
this.pubsub = pubsub
}

private getNoticeParams = (
private getNoticeParams = async (
params: NotificationPrarms,
language: LANGUAGES
): PutNoticeParams | undefined => {
): Promise<PutNoticeParams | undefined> => {
switch (params.event) {
case 'user_new_follower':
case 'comment_new_upvote':
Expand Down Expand Up @@ -113,6 +114,41 @@ export class NotificationService extends BaseService {
}),
entities: params.entities
}
case 'user_activated':
const invitation = params.entities[0].entity
const invitationSender = await this.baseFindById(
invitation.senderId,
'user'
)
const invitationRecipient = await this.baseFindById(
invitation.recipientId,
'user'
)

if (invitationSender.id === params.recipientId) {
return {
type: 'official_announcement',
recipientId: params.recipientId,
message: trans.user_activated_sender(language, {
displayName: invitationRecipient.displayName
})
}
}

if (invitationRecipient.id === params.recipientId) {
return {
type: 'official_announcement',
recipientId: params.recipientId,
message: trans.user_activated_recipient(language, {
displayName:
invitationSender.role !== USER_ROLE.admin
? invitationSender.displayName
: 'Matty'
})
}
}

return
default:
return
}
Expand All @@ -126,7 +162,7 @@ export class NotificationService extends BaseService {
return
}

const noticeParams = this.getNoticeParams(params, recipient.language)
const noticeParams = await this.getNoticeParams(params, recipient.language)

if (!noticeParams) {
return
Expand Down Expand Up @@ -159,7 +195,7 @@ export class NotificationService extends BaseService {
)

// Push Notification
this.push.push(noticeParams, params.event, recipient.language)
// this.push.push(noticeParams, params.event, recipient.language)
}

trigger = (params: NotificationPrarms) => {
Expand Down
Loading

0 comments on commit 5d1892c

Please sign in to comment.