Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
167 commits
Select commit Hold shift + click to select a range
7af6edc
feat: database and model setting
realyutou Aug 22, 2023
75e42e4
Update user.js
WinstonAdams Aug 22, 2023
76773de
Merge pull request #1 from realyutou/feature/model-setting
WinstonAdams Aug 22, 2023
eb33240
feat: add users seed
WinstonAdams Aug 22, 2023
7bbfeb8
feat: add user signup function
realyutou Aug 22, 2023
c3578fd
feat: add tweets seed
WinstonAdams Aug 22, 2023
b0f12bf
feat: add replies seed
WinstonAdams Aug 22, 2023
a767c4a
Merge pull request #2 from realyutou/feature/create-seeds
realyutou Aug 22, 2023
08fbcf7
feat: add seeds
WinstonAdams Aug 22, 2023
51623a4
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 22, 2023
10045ee
feat: add user signin function
realyutou Aug 22, 2023
9be7c57
feat: modify config.json for heroku
WinstonAdams Aug 23, 2023
d52b25d
feat: add auth middleware
realyutou Aug 23, 2023
807e2e7
feat: modify config.json for heroku
WinstonAdams Aug 23, 2023
e83d1c0
feat: add admin signin function
realyutou Aug 23, 2023
3784fb7
Merge pull request #3 from realyutou/feature/deploy-heroku
realyutou Aug 23, 2023
b6bcc6d
Update passport.js
WinstonAdams Aug 23, 2023
d685976
Merge branch 'master' into feature/signup-and-signin
WinstonAdams Aug 23, 2023
605c4ba
Merge pull request #4 from realyutou/feature/signup-and-signin
WinstonAdams Aug 23, 2023
8d99317
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 23, 2023
b891d24
feat: add heroku config
WinstonAdams Aug 23, 2023
9969ff6
feat: add signup and signin
realyutou Aug 23, 2023
bd0ab48
fix merge conflicts
realyutou Aug 23, 2023
4fc2d20
feat: add cors
WinstonAdams Aug 23, 2023
09979d7
Merge pull request #5 from realyutou/add-cors
realyutou Aug 23, 2023
81c3760
feat: add cors
WinstonAdams Aug 23, 2023
03ed4e0
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 23, 2023
e9977e2
feat: add admin getTweets function
WinstonAdams Aug 23, 2023
26a8aa4
feat: modify auth.js and add getTweet
realyutou Aug 23, 2023
5014211
feat: add admin deleteTweet function
WinstonAdams Aug 23, 2023
0e5c358
feat: add getTweets
realyutou Aug 23, 2023
34f7fd6
feat: add postTweet
realyutou Aug 23, 2023
b53ee46
feat: add getTweetReplies
realyutou Aug 23, 2023
d59cd97
feat: add postTweetReply
realyutou Aug 23, 2023
242d7c9
feat: add admin getUsers function
WinstonAdams Aug 23, 2023
d063638
modify admin getUsers function
WinstonAdams Aug 23, 2023
4cf7f87
modify admin getUsers function
WinstonAdams Aug 24, 2023
75f3e2f
Merge branch 'master' into feature/tweets
WinstonAdams Aug 24, 2023
3bf266e
Merge pull request #6 from realyutou/feature/tweets
WinstonAdams Aug 24, 2023
19d86b5
Merge branch 'master' into feature/admin-api
realyutou Aug 24, 2023
3e677d5
Merge pull request #7 from realyutou/feature/admin-api
realyutou Aug 24, 2023
5824ecf
feat: add admin api function
WinstonAdams Aug 24, 2023
7554cce
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 24, 2023
5a88afd
modify JWTSecret setting
realyutou Aug 24, 2023
53bac34
Merge pull request #8 from realyutou/feature/like
WinstonAdams Aug 24, 2023
2f7e823
modify routes/index.js
WinstonAdams Aug 24, 2023
b0db135
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 24, 2023
9a38876
add likeTweet function
realyutou Aug 24, 2023
d02016c
feat: add unlikeTweet function
realyutou Aug 24, 2023
6b7b190
Merge pull request #9 from realyutou/feature/like
WinstonAdams Aug 24, 2023
56b1ba4
feat: add followUser function
WinstonAdams Aug 24, 2023
4cab0ef
feat: add unfollowUser function
WinstonAdams Aug 24, 2023
5476b00
feat: add followship function
WinstonAdams Aug 24, 2023
a18b72a
Merge pull request #10 from realyutou/feature/followship-api
realyutou Aug 24, 2023
35c7d4f
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 24, 2023
9364967
feat: add getUser function
WinstonAdams Aug 24, 2023
ed930dd
feat: add putUser function
realyutou Aug 24, 2023
6a743da
feat: add getUserTweets function
WinstonAdams Aug 24, 2023
007a3de
feat: add getUserReplies function
WinstonAdams Aug 24, 2023
296dc20
modify getUserTweets function
WinstonAdams Aug 24, 2023
f9ea69c
feat: add getFollowings function
realyutou Aug 25, 2023
fbd4471
add getFollowers function
realyutou Aug 25, 2023
66089c8
feat: add getTopUser function
realyutou Aug 25, 2023
16d6619
Merge remote-tracking branch 'origin/master'
realyutou Aug 25, 2023
6048136
feat: add getUserLikes function
WinstonAdams Aug 25, 2023
2fbf104
feat: add order to getUserTweets、getUserReplies and getUserLikes func…
WinstonAdams Aug 25, 2023
2752f83
Merge pull request #11 from realyutou/feature/users-1
WinstonAdams Aug 25, 2023
1e0bb66
modify getUserLikes function
WinstonAdams Aug 26, 2023
74c7e47
Merge branch 'master' into feature/user-api
realyutou Aug 26, 2023
dd7b768
Merge pull request #12 from realyutou/feature/user-api
realyutou Aug 26, 2023
4306ecc
Merge remote-tracking branch 'origin/master'
realyutou Aug 26, 2023
098c626
feat: add user function
WinstonAdams Aug 26, 2023
1a61875
feat: set user account and password length range
realyutou Aug 26, 2023
03f8313
Update user-controller.js putUser function
WinstonAdams Aug 26, 2023
ca6d047
Merge pull request #13 from realyutou/feature/users-1
WinstonAdams Aug 26, 2023
c491b0f
feat: add user function from Github
WinstonAdams Aug 26, 2023
9bad055
feat: add token-test function
realyutou Aug 27, 2023
e95a5a8
Merge pull request #14 from realyutou/feature/auth-route
WinstonAdams Aug 27, 2023
8cf3873
modify getTopUser function
WinstonAdams Aug 27, 2023
b1a7e2f
Merge pull request #15 from realyutou/WinstonAdams-patch-1
realyutou Aug 27, 2023
cf04362
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 27, 2023
d799df3
Create README.md
WinstonAdams Aug 27, 2023
db6c553
Merge pull request #16 from realyutou/WinstonAdams-patch-2
realyutou Aug 27, 2023
05c2622
modify getUser function(add tweetsCount)
WinstonAdams Aug 28, 2023
2fd64b8
modify getTopUser function(exclude following users)
WinstonAdams Aug 28, 2023
32ef35d
feat: merge master
realyutou Aug 28, 2023
f94a412
Merge pull request #17 from realyutou/feature/user-api
realyutou Aug 28, 2023
f93cf6d
modify getUser and getTopUser function
WinstonAdams Aug 28, 2023
9029a0b
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 28, 2023
c25b6c5
modify deleteTweet function(一併將 tweet 相關的 replies 和 likes 刪除)
WinstonAdams Aug 28, 2023
c9b9038
Merge pull request #18 from realyutou/feature/user-api
realyutou Aug 28, 2023
c4a9baa
modify deleteTweet function(一併將 tweet 相關的 replies 和 likes 刪除)
WinstonAdams Aug 28, 2023
bda43d7
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 28, 2023
1ba0180
refactor getTweets function
WinstonAdams Aug 29, 2023
57fccbe
refactor deleteTweet function
WinstonAdams Aug 29, 2023
0d45624
refactor: modify user-controller getFollowings function
realyutou Aug 29, 2023
c364cb6
refactor: modify user-controller getFollowers function
realyutou Aug 29, 2023
23fba31
Merge branch 'master' into feature/users-1
realyutou Aug 29, 2023
3946e8c
feat: update user-controller putUser function
realyutou Aug 29, 2023
f0fb5e8
Merge branch 'master' into refactor-user-controller
realyutou Aug 29, 2023
96615a0
refactor: modify user-controler putUser function
realyutou Aug 29, 2023
1f0be0a
feat: update signin function
realyutou Aug 29, 2023
14facef
Update user-controller.js
WinstonAdams Aug 29, 2023
65252da
Merge pull request #19 from realyutou/feature/users-1
WinstonAdams Aug 29, 2023
1d8fb27
refactor getUsers function
WinstonAdams Aug 29, 2023
77aa281
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 29, 2023
0de0ee7
refactor: modify tweet-controller postTweet function
realyutou Aug 29, 2023
042243e
refactor: modify tweet-controller getTweetReplies function
realyutou Aug 29, 2023
1a530c4
refactor: modify tweet-controller postTweetReply
realyutou Aug 29, 2023
1a6ce94
modify signUp and putUser function(改成帳號已重複註冊!)
WinstonAdams Aug 30, 2023
74d1f27
modify getTopUser function
WinstonAdams Aug 30, 2023
15f5b20
Merge pull request #21 from realyutou/feature/user-api
realyutou Aug 30, 2023
e2008af
modify getTopUser、putUser and signUp
WinstonAdams Aug 30, 2023
71d2fc4
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 30, 2023
2264be5
refactor: modify user-controller getTopUsers function
realyutou Aug 30, 2023
8191daf
refactor: modify user-controller putUser function with Sequelize literal
realyutou Aug 30, 2023
e28f9f4
refactor tweet-controller getTweet function
realyutou Aug 30, 2023
8da27fb
refactor tweet-controller getTweets function
realyutou Aug 30, 2023
1cd2c29
refactor: tweet-controller likeTweet function
realyutou Aug 30, 2023
94a8f9c
refactor: tweet-controller unlikeTweet function
realyutou Aug 30, 2023
f6c56c4
refactor followUser function
WinstonAdams Aug 31, 2023
af46569
refactor unfollowUser function
WinstonAdams Aug 31, 2023
06d61e3
refactor getTopUser、getFollowers、getFollowings and putUser function
WinstonAdams Aug 31, 2023
081fca4
refactor getUser function
WinstonAdams Aug 31, 2023
985e422
refactor: passport-local-strategy
realyutou Aug 31, 2023
b850ae0
refactor getUserTweets function
WinstonAdams Aug 31, 2023
ac909dd
refactor getUserReplies function
WinstonAdams Aug 31, 2023
3098173
refactor: passport JWTStrategy
realyutou Aug 31, 2023
0c339de
refactor getUserLikes function
WinstonAdams Aug 31, 2023
70a03d2
modify getUserTweets and getUserLikes function
WinstonAdams Aug 31, 2023
4364ea0
refactor: modify admin-controller getTweets function
realyutou Aug 31, 2023
181e4bf
Merge pull request #20 from realyutou/refactor-admin-controller
realyutou Aug 31, 2023
bb11e18
refactor: modify getFollowers and getFollowings function
WinstonAdams Aug 31, 2023
b872e17
Merge branch 'master' into refactor-user-controller
WinstonAdams Aug 31, 2023
faded70
Merge pull request #22 from realyutou/refactor-user-controller
WinstonAdams Aug 31, 2023
25d98c5
Merge pull request #24 from realyutou/refactor-followship-controller
realyutou Aug 31, 2023
f5fc4ec
Refactor: modify user-controller getUser function
realyutou Aug 31, 2023
d016bbe
Merge pull request #23 from realyutou/refactor-tweet-controller
WinstonAdams Aug 31, 2023
cdcf127
Update package.json
realyutou Aug 31, 2023
f98fa7d
Merge branch 'master' into refactor-user-controller-2
realyutou Aug 31, 2023
02324d0
Merge pull request #26 from realyutou/refactor-user-controller-2
realyutou Aug 31, 2023
fb64549
Merge pull request #25 from realyutou/refactor-passport.js
WinstonAdams Aug 31, 2023
2277c9b
modify getUser function
WinstonAdams Aug 31, 2023
14ddff4
Merge pull request #27 from realyutou/refactor
realyutou Aug 31, 2023
5b124a2
Merge remote-tracking branch 'origin/master'
WinstonAdams Aug 31, 2023
a1df517
refactor deleteTweet function
WinstonAdams Sep 1, 2023
4c9221b
Merge remote-tracking branch 'origin/master' into refactor-admin-cont…
WinstonAdams Sep 1, 2023
c270c03
refactor followUser function
WinstonAdams Sep 1, 2023
566b44a
refactor unfollowUser function
WinstonAdams Sep 1, 2023
ad1e0fb
refactor: modify like and unlike function
realyutou Sep 1, 2023
984e9d1
refactor: modify getFollowers function
realyutou Sep 1, 2023
85b4b34
refactor: modify getFollowings function
realyutou Sep 1, 2023
ca88f6f
Merge pull request #30 from realyutou/refactor-1
WinstonAdams Sep 1, 2023
66e0529
refactor getUserTweets function
WinstonAdams Sep 1, 2023
5d824ef
refactor getUserReplies function
WinstonAdams Sep 1, 2023
fe0d0c9
refactor getUserLikes function
WinstonAdams Sep 1, 2023
e6fcd5d
Merge pull request #28 from realyutou/refactor-admin-controller
realyutou Sep 1, 2023
ad13b76
Merge pull request #29 from realyutou/refactor-followship-controller
realyutou Sep 1, 2023
4a36f1c
Merge pull request #31 from realyutou/refactor-user-controller-2
realyutou Sep 1, 2023
485d2f2
Merge remote-tracking branch 'origin/master'
WinstonAdams Sep 1, 2023
b7deba9
modify getTopUser function
WinstonAdams Sep 1, 2023
cedf137
feat: add email validator
WinstonAdams Sep 1, 2023
b55fd8e
Merge pull request #32 from realyutou/add-is.js
realyutou Sep 1, 2023
2115334
Update README.md (新增測試帳號)
WinstonAdams Sep 3, 2023
9fbb8e5
Merge pull request #33 from realyutou/WinstonAdams-patch-3
realyutou Sep 3, 2023
5d44cfc
fix: password.length could be 0
realyutou Sep 23, 2023
d4d2bfa
Merge pull request #34 from realyutou/fix-bug
WinstonAdams Sep 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
JWT_SECRET=
IMGUR_CLIENT_ID=
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules/*
/test/*
11 changes: 11 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
env:
browser: true
commonjs: true
es2021: true
extends: standard
parserOptions:
ecmaVersion: 12
rules:
arrow-parens:
- warn
- as-needed
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,6 @@ typings/
.fusebox/

# DynamoDB Local files
.dynamodb/
.dynamodb/

temp/
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: NODE_ENV=production node app.js
156 changes: 156 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Simple Twitter API

## 介紹

提供開發者可以串接多種功能的 API,接收特定 JSON 格式的 request,並回傳特定 JSON 格式的 response

## 功能

詳細功能說明可參考[ API 文件](https://nutritious-sun-1c3.notion.site/223aa71d1aad49c2938ed3e889eb593a?v=4717636d2df548588ffbed67d4884eec)
- 使用者註冊功能 API
- 使用者登入功能 API
- 修改使用者本身的資訊 API
- 特定使用者資訊 API
- 特定使用者發過的推文 API
- 特定使用者發過的回覆 API
- 特定使用者喜歡的推文 API
- 特定使用者跟隨中的人 API
- 特定使用者的跟隨者 API
- 跟隨者數量前 10 的推薦跟隨名單 API
- 特定推文 API
- 特定推文的全部回覆 API
- 全部推文 API
- 新增推文 API
- 新增特定推文的回覆 API
- 跟隨特定使用者 API
- 取消跟隨特定使用者 API
- 喜歡特定推文 API
- 取消特定喜歡的推文 API
- 管理者登入 API (僅供管理者使用)
- 全部推文 API (僅供管理者使用)
- 刪除特定推文 API (僅供管理者使用)
- 全部使用者 API (僅供管理者使用)


## 開始使用

1. 請先確認有安裝 Node.js 、 npm 、 MySQL 與 MySQL Workbench
2. 開啟終端機,到欲存放專案的路徑下,將專案 clone 到本地,輸入:

```bash
git clone https://github.com/realyutou/twitter-api-2020.git
```

3. 安裝相關套件,輸入:

```bash
npm install
```

4. 安裝 nodemon,輸入:

```bash
npm i -g nodemon
```

5. 新增 .env 檔案,設定環境變數,詳細內容可參考 .env.example

6. 開啟 MySQL Workbench,建立資料庫,輸入:

```SQL
create database ac_twitter_workspace;
```

7. 開啟終端機,建立資料表,輸入:

```bash
npx sequelize db:migrate
```

8. 載入種子資料,輸入:

```bash
npm run seed
```

9. 執行專案,輸入:

```bash
npm run dev
```

10. 在終端機看見以下訊息代表順利執行

```bash
Example app listening on port 3000!
```

11. 終止伺服器

```bash
ctrl + c
```

12. 若要開放給其他網域的開發者串接 API,可部署至雲端伺服器,以下操作以部署到 Heroku 為例:

13. 開啟終端機,登入 Heroku,輸入:

```bash
heroku login
```

14. 瀏覽器跳出登入頁面,登入 Heroku

15. 返回終端機,建立 Heroku 專案,輸入:

```bash
heroku create
```

16. 開啟 Heroku 專案設定頁面,新增連線遠端資料庫與 JWT_SECRET 的環境變數

17. 修改 config.json 檔案:

```json
"production": {
"use_env_variable": "<連線遠端資料庫的環境變數>"
}
```

18. 將本地專案推上 Heroku,輸入:

```bash
git push heroku <主要分支名稱>
```

19. 啟動 Heroku 上的專案,輸入:

```bash
heroku ps:scale web=1 -a <Heroku 專案名稱>
```

20. 開啟應用程式,利用網址即可對其他網域提供 API 接口

### 測試帳號

前台:
>- account: user1
>- email: user1@example.com
>- password: 12345678

後台:
>- account: root
>- email: root@example.com
>- password: 12345678


## 開發工具

- Node.js - 執行環境
- Express - Web 應用程式後端框架
- CORS - 跨網域發送請求套件
- Passport - 驗證機制套件
- JSON Web Token - 發送憑證套件
- Sequelize - 非同步 ORM 框架
- Dotenv - 設定環境變數套件
- ESLint - 定義程式碼風格套件
9 changes: 4 additions & 5 deletions _helpers.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@

function getUser(req) {
return req.user;
function getUser (req) {
return req.user
}

module.exports = {
getUser,
};
getUser
}
25 changes: 18 additions & 7 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config()
}

const express = require('express')
const helpers = require('./_helpers');
const routes = require('./routes')
const passport = require('./config/passport')
const cors = require('cors')

const app = express()
const port = 3000
const port = process.env.PORT || 3000

// Set body parser
app.use(express.urlencoded({ extended: true }))
app.use(express.json())

// 初始化 passport
app.use(passport.initialize())

// use helpers.getUser(req) to replace req.user
function authenticated(req, res, next){
// passport.authenticate('jwt', { ses...
};
app.use(cors())
// Set routes
app.use(routes)

app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

module.exports = app
8 changes: 2 additions & 6 deletions config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@
"logging": false
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
"use_env_variable": "MYSQL_DATABASE_URL"
},
"travis": {
"username": "travis",
Expand All @@ -34,4 +30,4 @@
"host": "127.0.0.1",
"dialect": "mysql"
}
}
}
57 changes: 56 additions & 1 deletion config/passport.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
const passport = require('passport')
const LocalStrategy = require('passport-local')
const passportJWT = require('passport-jwt')
const bcrypt = require('bcryptjs')
const Sequelize = require('sequelize')
const { User, Like, Tweet } = require('../models')

const JWTStrategy = passportJWT.Strategy
const ExtractJWT = passportJWT.ExtractJwt
const JWTSecret = process.env.JWT_SECRET || 'SECRET'

// 本地驗證
passport.use(new LocalStrategy({ usernameField: 'account' }, async (account, password, cb) => {
try {
const user = await User.findOne({
where: { account },
attributes: {
include: [
[Sequelize.literal('(SELECT COUNT(*) FROM `Tweets` WHERE `Tweets`.`UserId` = `User`.`id`)'), 'tweetsCount'],
[Sequelize.literal('(SELECT COUNT(*) FROM `Followships` WHERE `Followships`.`followingId` = `User`.`id`)'), 'followersCount'],
[Sequelize.literal('(SELECT COUNT(*) FROM `Followships` WHERE `Followships`.`followerId` = `User`.`id`)'), 'followingsCount']
]
},
raw: true
})
if (!user) {
const err = new Error('帳號不存在!')
err.status = 404
throw err
}
const result = await bcrypt.compare(password, user.password)
if (!result) throw new Error('密碼錯誤!')
delete user.password
return cb(null, user)
} catch (err) {
return cb(err, false)
}
}))

module.exports = passport
// 利用 jwtPayload 到資料庫找出 user 並傳入 req.user 供後續使用
const jwtOptions = {
jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken(),
secretOrKey: JWTSecret
}
passport.use(new JWTStrategy(jwtOptions, async (jwtPayload, cb) => {
try {
const user = await User.findByPk(jwtPayload.id, {
include: [
{ model: Like, include: Tweet },
{ model: User, as: 'Followers' },
{ model: User, as: 'Followings' }
]
})
return cb(null, user.toJSON())
} catch (err) {
return cb(err, false)
}
}))

module.exports = passport
Loading