Kaynağa Gözat

post next project

Bay 5 yıl önce
ebeveyn
işleme
f9e199c42a

+ 0 - 1
components/Navi.vue

@@ -86,7 +86,6 @@ export default {
       this.$store.commit('saveUser', {})
       this.$cookies.remove('token', { maxAge: 24 * 60 * 60 })
       this.$cookies.remove('user', { maxAge: 24 * 60 * 60 })
-      this.$cookies.removeAll()
       this.refresh()
       this.$router.push('/')
     },

+ 10 - 42
middleware/auth.js

@@ -1,57 +1,25 @@
 
 export default function (context) {
-  const {app, route, store, req, res, redirect, next} = context;
-  let isClient = process.client;
-  let isServer = process.server;
-  let token, path;
+  const { app, route, store, req, res, redirect, next } = context
+  const isClient = process.client
+  let token, path
 
-  token = store.state.token;
+  token = store.state.token
 
   // console.log('token', token);
 
   // console.log("cookies", cook);
-  //在服务端
-  if (isServer) {
-    path = req.originalUrl;
-  }
-  //在客户端判读是否需要登陆
+  // 在服务端
+  // 在客户端判读是否需要登陆
   if (isClient) {
-    path = route.path;
+    path = route.path
   }
 
   // console.log("path:"+path);
-  let mainPath = path.split("?")[0];
+  const mainPath = path.split('?')[0]
   // console.log('mainPath', mainPath);
 
-  if(mainPath === "/setToken"){
-    try{
-        let origin_path = app.$cookies.get('origin_path');
-
-        if(origin_path){
-          app.$cookies.remove('origin_path');
-          redirect(origin_path);
-        }else{
-          redirect('/');
-        }
-
-
-    }catch (e) {
-      console.log("e: ", e);
-      redirect('/error');
-    }
+  if (store.state.user.role !== 'ADMIN' && mainPath.indexOf('/admin') >= 0) {
+    redirect('/unauthorized')
   }
-
-  else if (!token && mainPath !== "/" && mainPath !=="/login" && mainPath !== "/register" && mainPath !=="/error" && mainPath !=="/resetPassword" && mainPath !=="/unauthorized" && mainPath !== "/api/receiveIDToken") {
-
-    // console.log("session:", req.session);
-    app.$cookies.set('origin_path', path);
-    // req.session.origin_path = path;
-    redirect('/api/authenticate');
-
-  }
-
-  else if(store.state.user.role !== 'ADMIN' && mainPath.indexOf('/admin') >= 0){
-    redirect('/unauthorized');
-  }
-
 }

+ 24 - 18
nuxt.config.js

@@ -1,16 +1,20 @@
 
 module.exports = {
-  mode: 'universal',
+  ssr: false,
   /*
   ** Headers of the page
   */
   head: {
-    title: "SEEC软件工程教育云平台", //process.env.npm_package_name || '',
+    title: 'SEEC软件工程教育云平台', // process.env.npm_package_name || '',
     meta: [
       { charset: 'utf-8' },
       { name: 'viewport', content: 'width=device-width, initial-scale=1' },
-      { hid: 'description', name: 'description', content: process.env.npm_package_description ||
-        'SEEC软件工程教育云平台,一个旨在为在校学生或行业内人士,提供系统性自主学习软件工程领域知识服务的平台' }
+      {
+        hid: 'description',
+        name: 'description',
+        content: process.env.npm_package_description ||
+        'SEEC软件工程教育云平台,一个旨在为在校学生或行业内人士,提供系统性自主学习软件工程领域知识服务的平台'
+      }
     ],
     link: [
       { rel: 'icon', type: 'image/x-icon', href: '/seec.ico' }
@@ -31,9 +35,10 @@ module.exports = {
   ** Plugins to load before mounting the App
   */
   plugins: [
-    {src: '@/plugins/element-ui', ssr: true},
+    { src: '@/plugins/element-ui', ssr: true },
+    { src: '~/plugins/vuex-persist', ssr: false },
     '~/plugins/api',
-     '~plugins/echarts'
+    '~plugins/echarts'
   ],
   /*
   ** Nuxt.js dev-modules
@@ -46,7 +51,8 @@ module.exports = {
   modules: [
     '@nuxtjs/axios',
     '@nuxtjs/style-resources',
-    'cookie-universal-nuxt'
+    'cookie-universal-nuxt',
+    '@nuxtjs/proxy'
   ],
 
   router: {
@@ -54,7 +60,7 @@ module.exports = {
   },
 
   styleResources: {
-    scss: './assets/css/main.scss',
+    scss: './assets/css/main.scss'
   },
   /*
   ** Build configuration
@@ -71,17 +77,17 @@ module.exports = {
   axios: {
     proxy: false,
     prefix: '/api', // baseURL
-    credentials: true,
+    credentials: true
   },
-  // proxy: {
-  //   '/api/': {
-  //     target: 'http://localhost:8080', // 代理地址
-  //     // changeOrigin: true,
-  //     // pathRewrite: {
-  //     //   '^/api': ''
-  //     // },
-  //   },
-  // },
+  proxy: {
+    '/api/': {
+      target: 'http://localhost:8080' // 代理地址
+      // changeOrigin: true,
+      // pathRewrite: {
+      //   '^/api': ''
+      // },
+    }
+  }
 
   // server: {
   //   https: true

Dosya farkı çok büyük olduğundan ihmal edildi
+ 509 - 189
package-lock.json


+ 7 - 21
package.json

@@ -5,9 +5,9 @@
   "author": "Starink",
   "private": true,
   "scripts": {
-    "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
+    "dev": "nuxt dev",
     "build": "nuxt build",
-    "start": "cross-env NODE_ENV=production node server/index.js",
+    "start": "nuxt start",
     "generate": "nuxt generate",
     "test": "jest"
   },
@@ -26,32 +26,18 @@
     "echarts": "^4.7.0",
     "element-ui": "^2.4.11",
     "jsonwebtoken": "^8.5.1",
-    "koa": "^2.6.2",
-    "koa-bodyparser": "^4.2.1",
-    "koa-convert": "^1.2.0",
-    "koa-helmet": "^5.2.0",
-    "koa-json": "^2.0.2",
-    "koa-jwt": "^3.6.0",
-    "koa-logger": "^3.2.0",
-    "koa-mount": "^4.0.0",
-    "koa-onerror": "^4.1.0",
-    "koa-router": "^7.4.0",
-    "koa-session": "^5.13.1",
-    "koa-static": "^5.0.0",
-    "koa-views": "^6.2.0",
-    "koa2-cors": "^2.0.6",
     "lodash": "^4.17.15",
-    "mysql": "^2.18.1",
-    "mysql2": "^2.1.0",
-    "nuxt": "^2.0.0",
+    "nuxt": "^2.15.4",
     "oidc-provider": "^6.23.1",
     "openid-client": "^3.14.0",
     "pug": "^2.0.3",
     "request": "^2.88.2",
-    "sequelize": "^5.21.4",
-    "util": "^0.12.1"
+    "util": "^0.12.1",
+    "vue": "^2.6.12",
+    "vuex-persist": "^3.1.3"
   },
   "devDependencies": {
+    "@nuxtjs/proxy": "^2.1.0",
     "@vue/test-utils": "^1.0.0-beta.27",
     "babel-jest": "^24.1.0",
     "chai": "^4.2.0",

+ 0 - 28
pages/index.vue

@@ -1,24 +1,5 @@
 <template>
   <div>
-    <!--<el-menu-->
-      <!--default-active="1"-->
-      <!--class="el-menu-demo"-->
-      <!--mode="horizontal"-->
-      <!--active-text-color="#409eff">-->
-      <!--<el-menu-item index="0"><image src="/image/seec_logo&#45;&#45;bw.png" class="nav__logo" /></el-menu-item>-->
-      <!--<el-menu-item index="1"><a href="http://mooc.seecoder.cn" target="_self">软工一</a></el-menu-item>-->
-      <!--<el-menu-item index="2"><a href="http://bok.seecoder.cn" target="_self">题库</a></el-menu-item>-->
-      <!--<el-menu-item index="3"><a href="http://helper.seecoder.cn" target="_self">学习助手</a></el-menu-item>-->
-    <!--</el-menu>-->
-
-    <!--<img class="home-banner" src="/image/SEEC_banner.png"/>-->
-    <!--<div class="hot-courses">-->
-      <!--<h2 class="hot-courses__title">热门课程</h2>-->
-      <!--<div class="hot-courses__list">-->
-        <!--一波精品课程正在内测中,敬请期待!-->
-      <!--</div>-->
-    <!--</div>-->
-
     <img class="home-banner" src="/image/SEEC_banner3.png"/>
     <h1 class="title">热门课程</h1>
     <div class="course-list">
@@ -50,14 +31,11 @@
 </template>
 
 <script>
-import Logo from '~/components/Logo.vue'
 import CourseCard from '~/components/CourseCard'
 import ColumnCard from '~/components/ColumnCard'
-import { mapState } from 'vuex'
 
 export default {
   components: {
-    Logo,
     CourseCard,
     ColumnCard
   },
@@ -108,12 +86,6 @@ export default {
 
       ]
     }
-  },
-  mounted () {
-    // this.$cookies.removeAll();
-    // this.$store.commit('saveToken', null);
-    // this.$store.commit('saveUser', {});
-
   }
 }
 </script>

+ 7 - 4
pages/login.vue

@@ -22,7 +22,6 @@
 </template>
 
 <script>
-import { mapState } from 'vuex'
 import SIdentify from '~/components/Identify'
 
 export default {
@@ -148,14 +147,18 @@ export default {
             localStorage.removeItem('rememberPassword')
           }
 
-          // this.$store.commit("saveUser", res.data.user);
-          // this.$store.commit("saveToken", res.data.token);
           this.$message({
             showClose: true,
             message: '欢迎回来,' + res.data.name,
             type: 'success'
           })
-          window.location.href = res.data.path + '?id_token=' + res.data.token
+          this.$store.commit('saveToken', res.data.token)
+          this.$store.commit('saveUser', res.data.user)
+          if (!res.data.path) {
+            this.$router.push('/')
+          } else {
+            window.location.href = res.data.path + '?id_token=' + res.data.token
+          }
         } else {
           this.$message({
             showClose: true,

+ 1 - 1
pages/person/identification.vue

@@ -70,7 +70,7 @@ export default {
     }
   },
   mounted () {
-    this.$api.get('/teacher/getInfo', {
+    this.$api.$get('/teacher/getInfo', {
       realName: this.realName,
       jobNumber: this.jobNumber,
       organization: this.organization

+ 0 - 20
pages/person/info.vue

@@ -244,26 +244,6 @@ export default {
       this.loading = false
     }
   }
-  // asyncData ({ app, params, error, store }) {
-  //   return app.$api.post(`http://localhost:3000/api/user/getInfo`,  {
-  //     uid: store.state.user.id
-  //   })
-  //     .then((res) => {
-  //       let data = res.data.data;
-  //       return { name: data.name, signature: data.signature, email: data.email }
-  //     })
-  //     .catch((e) => {
-  //       console.log(e);
-  //       error({ statusCode: 404, message: 'Post not found' })
-  //     })
-  // }
-  // asyncData(ctx){
-  //   console.log("info ctx.app",  ctx.app)
-  //   console.log("info ctx.app.$api:",  ctx.app.$api)
-  //   console.log("info ctx.$api:",  ctx.$api)
-  //   console.log("info ctx.$axios:",  ctx.$axios)
-  //   return {};
-  // }
 }
 </script>
 

+ 0 - 2
plugins/api.js

@@ -50,7 +50,6 @@ export default function ({ $axios, redirect, app, store }, inject) {
 
   api.onResponse(response => {
     if (response.status === 401) {
-      app.$cookies.removeAll()
       store.commit('saveToken', null)
       store.commit('saveUser', {})
       redirect('/unauthorized')
@@ -59,7 +58,6 @@ export default function ({ $axios, redirect, app, store }, inject) {
 
   api.onError(error => {
     if (error.response.status === 401) {
-      app.$cookies.removeAll()
       store.commit('saveToken', null)
       store.commit('saveUser', {})
       redirect('/unauthorized')

+ 8 - 0
plugins/vuex-persist.js

@@ -0,0 +1,8 @@
+
+import VuexPersistence from 'vuex-persist'
+
+export default ({ store }) => {
+  new VuexPersistence({
+  /* your options */
+  }).plugin(store)
+}

+ 0 - 11
server/.babelrc

@@ -1,11 +0,0 @@
-{
-  "env": {
-    "test": {
-      "presets": ["es2015-node5"],
-      "plugins": [
-        "transform-async-to-generator",
-        "syntax-async-functions"
-      ]
-    }
-  }
-}

+ 0 - 0
server/README.md


+ 0 - 87
server/adapters/memory_adapter.js

@@ -1,87 +0,0 @@
-const LRU = require('lru-cache')
-
-const epochTime = require('../helpers/epoch_time')
-
-let storage = new LRU({})
-
-function grantKeyFor (id) {
-  return `grant:${id}`
-}
-
-function sessionUidKeyFor (id) {
-  return `sessionUid:${id}`
-}
-
-function userCodeKeyFor (userCode) {
-  return `userCode:${userCode}`
-}
-
-class MemoryAdapter {
-  constructor (model) {
-    this.model = model
-  }
-
-  key (id) {
-    return `${this.model}:${id}`
-  }
-
-  async destroy (id) {
-    const key = this.key(id)
-    storage.del(key)
-  }
-
-  async consume (id) {
-    storage.get(this.key(id)).consumed = epochTime()
-  }
-
-  async find (id) {
-    return storage.get(this.key(id))
-  }
-
-  async findByUid (uid) {
-    const id = storage.get(sessionUidKeyFor(uid))
-    return this.find(id)
-  }
-
-  async findByUserCode (userCode) {
-    const id = storage.get(userCodeKeyFor(userCode))
-    return this.find(id)
-  }
-
-  async upsert (id, payload, expiresIn) {
-    const key = this.key(id)
-
-    if (this.model === 'Session') {
-      storage.set(sessionUidKeyFor(payload.uid), id, expiresIn * 1000)
-    }
-
-    const { grantId, userCode } = payload
-    if (grantId) {
-      const grantKey = grantKeyFor(grantId)
-      const grant = storage.get(grantKey)
-      if (!grant) {
-        storage.set(grantKey, [key])
-      } else {
-        grant.push(key)
-      }
-    }
-
-    if (userCode) {
-      storage.set(userCodeKeyFor(userCode), id, expiresIn * 1000)
-    }
-
-    storage.set(key, payload, expiresIn * 1000)
-  }
-
-  async revokeByGrantId (grantId) { // eslint-disable-line class-methods-use-this
-    const grantKey = grantKeyFor(grantId)
-    const grant = storage.get(grantKey)
-    if (grant) {
-      grant.forEach((token) => storage.del(token))
-      storage.del(grantKey)
-    }
-  }
-}
-
-module.exports = MemoryAdapter
-module.exports.setStorage = (store) => { storage = store }

+ 0 - 114
server/adapters/sequelize.js

@@ -1,114 +0,0 @@
-/*
- * This is a very rough-edged example, the idea is to still work with the fact that oidc-provider
- * has a rather "dynamic" schema. This example uses sequelize with postgresql, and all dynamic data
- * uses JSON fields. id is set to be the primary key, grantId should be additionaly indexed for
- * models where these fields are set (grantId-able models). userCode should be additionaly indexed
- * for DeviceCode model. uid should be additionaly indexed for Session model. For sequelize
- * migrations @see https://github.com/Rogger794/node-oidc-provider/tree/examples/example/migrations/sequelize
-*/
-
-// npm i sequelize@^5.21.2
-const Sequelize = require('sequelize') // eslint-disable-line import/no-unresolved
-
-const sequelize = new Sequelize('seec_sso', 'root', '981018', {
-  host: 'localhost',
-  port: 3306,
-  dialect: 'mysql'
-})
-
-const grantable = new Set([
-  'AccessToken',
-  'AuthorizationCode',
-  'RefreshToken',
-  'DeviceCode'
-])
-
-const models = [
-  'Session',
-  'AccessToken',
-  'AuthorizationCode',
-  'RefreshToken',
-  'DeviceCode',
-  'ClientCredentials',
-  'Client',
-  'InitialAccessToken',
-  'RegistrationAccessToken',
-  'Interaction',
-  'ReplayDetection',
-  'PushedAuthorizationRequest'
-].reduce((map, name) => {
-  map.set(name, sequelize.define(name, {
-    id: { type: Sequelize.STRING, primaryKey: true },
-    ...(grantable.has(name) ? { grantId: { type: Sequelize.STRING } } : undefined),
-    ...(name === 'DeviceCode' ? { userCode: { type: Sequelize.STRING } } : undefined),
-    ...(name === 'Session' ? { uid: { type: Sequelize.STRING } } : undefined),
-    data: { type: Sequelize.JSONB },
-    expiresAt: { type: Sequelize.DATE },
-    consumedAt: { type: Sequelize.DATE }
-  }))
-
-  return map
-}, new Map())
-
-class SequelizeAdapter {
-  constructor (name) {
-    this.model = models.get(name)
-    this.name = name
-  }
-
-  async upsert (id, data, expiresIn) {
-    await this.model.upsert({
-      id,
-      data,
-      ...(data.grantId ? { grantId: data.grantId } : undefined),
-      ...(data.userCode ? { userCode: data.userCode } : undefined),
-      ...(data.uid ? { uid: data.uid } : undefined),
-      ...(expiresIn ? { expiresAt: new Date(Date.now() + (expiresIn * 1000)) } : undefined)
-    })
-  }
-
-  async find (id) {
-    const found = await this.model.findByPk(id)
-    if (!found) return undefined
-    return {
-      ...found.data,
-      ...(found.consumedAt ? { consumed: true } : undefined)
-    }
-  }
-
-  async findByUserCode (userCode) {
-    const found = await this.model.findOne({ where: { userCode } })
-    if (!found) return undefined
-    return {
-      ...found.data,
-      ...(found.consumedAt ? { consumed: true } : undefined)
-    }
-  }
-
-  async findByUid (uid) {
-    const found = await this.model.findOne({ where: { uid } })
-    if (!found) return undefined
-    return {
-      ...found.data,
-      ...(found.consumedAt ? { consumed: true } : undefined)
-    }
-  }
-
-  async destroy (id) {
-    await this.model.destroy({ where: { id } })
-  }
-
-  async consume (id) {
-    await this.model.update({ consumedAt: new Date() }, { where: { id } })
-  }
-
-  async revokeByGrantId (grantId) {
-    await this.model.destroy({ where: { grantId } })
-  }
-
-  static async connect () {
-    return sequelize.sync()
-  }
-}
-
-module.exports = SequelizeAdapter

+ 0 - 91
server/bin/www

@@ -1,91 +0,0 @@
-// #!/usr/bin/env node
-//
-// /**
-//  * Module dependencies.
-//  */
-//
-// var app = require('../app');
-// var debug = require('debug')('demo:server');
-// var http = require('http');
-//
-// /**
-//  * Get port from environment and store in Express.
-//  */
-//
-// var port = normalizePort(process.env.PORT || '8080');
-// // app.set('port', port);
-//
-// /**
-//  * Create HTTP server.
-//  */
-//
-// var server = http.createServer(app.callback());
-//
-// /**
-//  * Listen on provided port, on all network interfaces.
-//  */
-//
-// server.listen(port);
-// console.log("server at port " + port);
-// server.on('error', onError);
-// server.on('listening', onListening);
-//
-// /**
-//  * Normalize a port into a number, string, or false.
-//  */
-//
-// function normalizePort(val) {
-//   var port = parseInt(val, 10);
-//
-//   if (isNaN(port)) {
-//     // named pipe
-//     return val;
-//   }
-//
-//   if (port >= 0) {
-//     // port number
-//     return port;
-//   }
-//
-//   return false;
-// }
-//
-// /**
-//  * Event listener for HTTP server "error" event.
-//  */
-//
-// function onError(error) {
-//   if (error.syscall !== 'listen') {
-//     throw error;
-//   }
-//
-//   var bind = typeof port === 'string'
-//     ? 'Pipe ' + port
-//     : 'Port ' + port;
-//
-//   // handle specific listen errors with friendly messages
-//   switch (error.code) {
-//     case 'EACCES':
-//       console.error(bind + ' requires elevated privileges');
-//       process.exit(1);
-//       break;
-//     case 'EADDRINUSE':
-//       console.error(bind + ' is already in use');
-//       process.exit(1);
-//       break;
-//     default:
-//       throw error;
-//   }
-// }
-//
-// /**
-//  * Event listener for HTTP server "listening" event.
-//  */
-//
-// function onListening() {
-//   var addr = server.address();
-//   var bind = typeof addr === 'string'
-//     ? 'pipe ' + addr
-//     : 'port ' + addr.port;
-//   debug('Listening on ' + bind);
-// }

+ 0 - 10
server/config/db.js

@@ -1,10 +0,0 @@
-const Sequelize = require('sequelize')
-
-const sequelize = new Sequelize('mysql://root:123456@localhost:3306/seec_portal', {
-// const sequelize = new Sequelize('mysql://root:NJU67mysql@172.29.7.180:3306/seec_portal', {
-  define: { timestamps: false },
-  timezone: '+08:00' // 东八时区
-})
-
-sequelize.sync({ alter: true })
-module.exports = sequelize

+ 0 - 3
server/config/secret.json

@@ -1,3 +0,0 @@
-{
-  "sign": "SEEC-1919810-OIDC-114514"
-}

+ 0 - 79
server/controller/admin.js

@@ -1,79 +0,0 @@
-const teacherModel = require('../model/teacher')
-const userModel = require('../model/user')
-const Response = require('../util/response')
-const getTokenUser = require('../util/tokenProcessor')
-
-class AdminController {
-  static async getApplications (ctx) {
-    const theUser = await getTokenUser(ctx)
-    if (theUser.role !== 'ADMIN') {
-      ctx.status = 401
-    } else {
-      const result = await teacherModel.getApplications()
-      if (result) {
-        ctx.body = Response.success(result)
-      } else {
-        ctx.body = Response.failed('获取失败')
-      }
-    }
-  }
-
-  static async getUsers (ctx) {
-    const theUser = await getTokenUser(ctx)
-    if (theUser.role !== 'ADMIN') {
-      ctx.status = 401
-    } else {
-      const result = await userModel.getUsers()
-      if (result) {
-        ctx.body = Response.success(result)
-      } else {
-        ctx.body = Response.failed('获取失败')
-      }
-    }
-  }
-
-  static async updateUser (ctx) {
-    const theUser = await getTokenUser(ctx)
-    if (theUser.role !== 'ADMIN') {
-      ctx.status = 401
-    } else {
-      const result = await userModel.updateIsValid(ctx.request.body.id, ctx.request.body.isValid)
-      if (result) {
-        ctx.body = Response.success(result)
-      } else {
-        ctx.body = Response.failed('获取失败')
-      }
-    }
-  }
-
-  static async passApplication (ctx) {
-    const theUser = await getTokenUser(ctx)
-    if (theUser.role !== 'ADMIN') {
-      ctx.status = 401
-    } else {
-      let result = await teacherModel.updateState(ctx.request.body.id, 'identified')
-      result = result && await userModel.identifyTeacher(ctx.request.body.uid)
-      if (result) {
-        ctx.body = Response.success(result)
-      } else {
-        ctx.body = Response.failed('否决失败,请重试')
-      }
-    }
-  }
-
-  static async rejectApplication (ctx) {
-    const theUser = await getTokenUser(ctx)
-    if (theUser.role !== 'ADMIN') {
-      ctx.status = 401
-    } else {
-      const result = await teacherModel.updateState(ctx.request.body.id, 'rejected')
-      if (result) {
-        ctx.body = Response.success(result)
-      } else {
-        ctx.body = Response.failed('通过失败,请重试')
-      }
-    }
-  }
-}
-
-module.exports = AdminController

+ 0 - 103
server/controller/auth.js

@@ -1,103 +0,0 @@
-const Response = require('../util/response')
-const jwt = require('jsonwebtoken')
-
-class AuthController {
-  static checkClient (ctx) {
-    const allowed_client_ids = ['seec-portal', 'seec-seec', 'seec-mooc', 'seec-helper']
-    const allowed_redirect_domains = ['localhost:3000', 'localhost:8000', 'p.seecoder.cn', 'seec.seecoder.cn', 'mooc.seecoder.cn', 'helper.seecoder.cn',
-      'mooc-test.seecoder.cn', 'seec-test.seecoder.cn', 'p-test.seecoder.cn', 'helper-test.seecoder.cn', 'seecoder.cn']
-
-    const query = ctx.query
-    // console.log('query', query);
-
-    const { client_id, redirect_uri, scope } = query
-    if (!client_id || !redirect_uri || !scope) {
-      ctx.body = Response.failed('非法请求,拒绝访问')
-    } else if (allowed_client_ids.indexOf(client_id) < 0 || scope !== 'openid' || (redirect_uri.indexOf('https://') !== 0 && redirect_uri.indexOf('http://') !== 0)) {
-      ctx.body = Response.failed('非法请求,拒绝访问')
-    } else {
-      const durl = /http:\/\/([^\/]+)\//i
-      const domain = redirect_uri.match(durl)[1]
-      // console.log('domain',domain);
-      if (allowed_redirect_domains.filter(item => domain.indexOf(item) >= 0).length == 0) {
-        ctx.body = Response.failed('非法请求,拒绝访问')
-      } else {
-        ctx.cookies.set('redirect_uri', redirect_uri, {
-          maxAge: 60 * 1000 * 3
-        })
-        ctx.cookies.set('client_id', client_id, {
-          maxAge: 60 * 1000 * 3
-        })
-        ctx.redirect('/login')
-      }
-    }
-  }
-
-  static processIDToken (ctx) {
-    const query = ctx.query
-    const { id_token } = query
-    if (!id_token) {
-      ctx.body = Response.failed('非法请求!')
-    } else {
-      jwt.verify(id_token, 'SEEC-1919810-OIDC-114514', (err, authData) => {
-        if (err) {
-          console.log('err:', err)
-          ctx.redirect('/error')
-        } else {
-          const { iss, sub, aud, auth_time, iat, exp, user_info } = authData
-          if (!iss || !sub || !aud || !auth_time || !iat || !exp || !user_info) {
-            ctx.redirect('/error')
-          } else if (iss !== 'p.seecoder.cn' || aud !== 'seec-portal') {
-            ctx.redirect('/error')
-          } else {
-            const user = user_info
-            const my_token = jwt.sign(
-              user, 'SEEC-1919810-OIDC-114514', { expiresIn: '1day' }
-            )
-
-            // console.log("user", user_info);
-
-            ctx.session.maxAge = 1000
-
-            ctx.session.token = my_token
-            ctx.session.user = user
-
-            // console.log('state.origin_path', ctx.state.origin_path);
-
-            ctx.redirect('/setToken')
-            // console.log('$cookies', ctx.app.$cookies);
-
-            // ctx.res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
-            // ctx.res.setHeader("Access-Control-Allow-Credentials", true);
-
-            // ctx.cookies.user = user;
-            // ctx.cookies.token = my_token;
-            //
-            // console.log("origin_path", origin_path)
-            //
-            // ctx.redirect(origin_path);
-
-            // let url = '/setToken?token=' + my_token + '&id=' + user.id + '&name=' + user.name + '&phone=' + user.phone;
-            // ctx.redirect(url);
-          }
-        }
-      })
-    }
-  }
-
-  static authenticate (ctx) {
-    const query = ctx.query
-
-    const return_uri = encodeURIComponent(ctx.origin + '/api/receiveIDToken')
-    const url = ctx.origin + '/api/interaction?' +
-      'client_id=' + 'seec-portal' +
-      '&scope=openid' +
-      '&redirect_uri=' + return_uri
-
-    // console.log("redirect to " + url);
-
-    return ctx.redirect(url)
-  }
-}
-
-module.exports = AuthController

+ 0 - 36
server/controller/course.js

@@ -1,36 +0,0 @@
-const myRequest = require('../util/request')
-const Response = require('../util/response')
-
-class CourseController {
-  /**
-     * 获取热门课程
-     * @param ctx
-     * @returns {Promise.<void>}
-     */
-  static async getHotCourses (ctx) {
-    const { uid } = ctx.request.query
-    const courses = await myRequest('http://mooc.seecoder.cn/api/statistic/hotCourses')
-    if (courses) {
-      ctx.body = Response.success({ hotCourses: courses })
-    } else {
-      ctx.body = Response.failed('获取热门课程失败')
-    }
-  }
-
-  /**
-     * 获取我的课程
-     * @param ctx
-     * @returns {Promise.<void>}
-     */
-  static async getMyCourses (ctx) {
-    const { uid } = ctx.request.query
-    const courses = await myRequest('http://mooc.seecoder.cn/api/statistic/myCourses/' + uid)
-    if (courses) {
-      ctx.body = Response.success({ myCourses: courses })
-    } else {
-      ctx.body = Response.failed('获取当前课程失败')
-    }
-  }
-}
-
-module.exports = CourseController

+ 0 - 53
server/controller/teacher.js

@@ -1,53 +0,0 @@
-const teacherModel = require('../model/teacher')
-const Response = require('../util/response')
-const getTokenUser = require('../util/tokenProcessor')
-
-class TeacherController {
-  static async getInfo (ctx) {
-    const theUser = await getTokenUser(ctx)
-    const teacher = await teacherModel.findByUid(theUser.id)
-    if (teacher) {
-      ctx.body = Response.success({ realName: teacher.realName, certificate: teacher.certificate, organization: teacher.organization, jobNumber: teacher.jobNumber, state: teacher.state })
-    } else {
-      ctx.body = Response.failed('此教师不存在')
-    }
-  }
-
-  static async apply (ctx) {
-    const theUser = await getTokenUser(ctx)
-    const data = ctx.request.body
-    const result = await teacherModel.create({ ...data, ...theUser })
-    if (result) {
-      ctx.body = Response.success({})
-    } else {
-      ctx.body = Response.failed('参数错误')
-    }
-  }
-
-  static async reapply (ctx) {
-    const theUser = await getTokenUser(ctx)
-    const data = ctx.request.body
-    const result = await teacherModel.updateInfo({ ...data, uid: theUser.id })
-    if (result) {
-      ctx.body = Response.success({})
-    } else {
-      ctx.body = Response.failed('参数错误')
-    }
-  }
-
-  static async getApplications (ctx) {
-    const theUser = await getTokenUser(ctx)
-    if (theUser.role !== 'ADMIN') {
-      ctx.status = 401
-    } else {
-      const result = await teacherModel.getApplications()
-      if (result) {
-        ctx.body = Response.success(result)
-      } else {
-        ctx.body = Response.failed('获取失败')
-      }
-    }
-  }
-}
-
-module.exports = TeacherController

+ 0 - 249
server/controller/user.js

@@ -1,249 +0,0 @@
-const userModel = require('../model/user')
-const jwt = require('jsonwebtoken')
-const bcrypt = require('bcrypt')
-const secret = require('../config/secret')
-const Response = require('../util/response')
-const aliClient = require('../util/aliClient')
-const getTokenUser = require('../util/tokenProcessor')
-
-class UserController {
-  /**
-     * 登录
-     * @param ctx
-     * @returns {Promise.<void>}
-     */
-  static async login (ctx) {
-    const data = ctx.request.body
-    const user = await userModel.findByPhone(data.phone)
-    if (user) {
-      const confirmRes = bcrypt.compareSync(data.password, user.password)
-      if (!confirmRes) {
-        ctx.body = Response.failed('密码错误,请重试')
-      } else if (!user.isValid) {
-        ctx.body = Response.failed('账号封禁中')
-      } else {
-        // console.log('ctx',ctx);
-        // console.log('ctx.cookies.redirect_uri',ctx.cookies.get('redirect_uri'));
-        let redirectUri = ctx.cookies.get('redirect_uri')
-        let clientId = ctx.cookies.get('client_id')
-
-        if (!redirectUri) {
-          redirectUri = ctx.origin + '/api/receiveIDToken'
-        }
-        if (!clientId) {
-          clientId = 'seec-portal'
-        }
-
-        const data = {
-          iss: 'p.seecoder.cn',
-          sub: user.phone,
-          aud: clientId,
-          auth_time: Math.floor(new Date().getTime() / 1000),
-          iat: Math.floor(new Date().getTime() / 1000),
-          exp: Math.floor(new Date().getTime() / 1000 + 24 * 60 * 60),
-          user_info: { phone: user.phone, email: user.email, id: user.id, name: user.name, role: user.role }
-        }
-        const token = jwt.sign(data, secret.sign)
-
-        // ctx.redirect(redirect_uri + "?id_token=" + token);
-        ctx.cookies.set('redirect_uri', '', {
-          maxAge: 0
-        })
-        ctx.cookies.set('client_id', '', {
-          maxAge: 0
-        })
-
-        ctx.body = Response.success({ token: token, name: user.name, path: redirectUri })
-      }
-    } else {
-      ctx.body = Response.failed('此账号不存在')
-    }
-  }
-
-  /**
-     * 注册
-     * @param ctx
-     * @returns {Promise.<void>}
-     */
-  static async register (ctx) {
-    const myReg = /^[a-zA-Z0-9_-]+@([a-zA-Z0-9]+\.)+(com|cn|net|org)$/
-    const myReg2 = /^\w+$/
-    const data = ctx.request.body
-
-    if (!ctx.session.verification_phone || !ctx.session.verification_code) {
-      ctx.body = Response.failed('请重新获取验证码')
-    } else if (ctx.session.verification_code !== data.identifyCode || ctx.session.verification_phone !== data.phone) {
-      ctx.body = Response.failed('验证码错误')
-    } else if (!myReg.test(data.email)) {
-      ctx.body = Response.failed('邮箱格式有误')
-    } else if (data.name.length < 1 || data.name.length > 10 || data.password.length < 6 || data.password.length > 20 || data.phone.length !== 11 || !myReg2.test(data.name)) {
-      ctx.body = Response.failed('参数非法')
-    } else {
-      const hashPassword = bcrypt.hashSync(data.password, 10)
-      const result = await userModel.create(data.name, hashPassword, data.phone, data.email)
-      ctx.session.verification_phone = undefined
-      ctx.session.verification_code = undefined
-      if (result.code === 0) {
-        ctx.body = Response.success({ name: result.data.name })
-      } else if (result.code === -2) {
-        ctx.body = Response.failed('此手机号已注册')
-      } else if (result.code === -1) {
-        ctx.body = Response.failed('此用户名已使用')
-      }
-    }
-  }
-
-  static async sendMessage (ctx) {
-    const { phone } = ctx.request.body
-
-    let code = ''
-    for (let i = 0; i < 6; i++) {
-      code += Math.floor(Math.random() * 10)
-    }
-    const params = {
-      PhoneNumbers: phone,
-      SignName: 'seeccoder',
-      TemplateCode: 'SMS_181555598',
-      TemplateParam: '{"code":"' + code + '"}'
-    }
-    // TODO: ??? 这里写个 options 到底是要干啥
-    // const options = {
-    //   timeout: 3000, // default 3000 ms
-    //   formatAction: true, // default true, format the action to Action
-    //   formatParams: true, // default true, format the parameter name to first letter upper case
-    //   method: 'GET', // set the http method, default is GET
-    //   headers: {} // set the http request headers
-    // }
-    try {
-      const result = await aliClient.request('SendSms', params)
-      // console.log("result:", result);
-      if (result.Code === 'OK') {
-        ctx.session.maxAge = 5 * 60 * 1000
-        ctx.session.verification_code = code
-        ctx.session.verification_phone = phone
-        // console.log('verification_code:', ctx.session.verification_code);
-        ctx.body = Response.success({ message: '发送成功' })
-      } else {
-        console.log('error:', result.message)
-        ctx.body = Response.failed('发送失败,请重试')
-      }
-    } catch (e) {
-      console.log(e)
-      ctx.body = Response.failed('发送失败,请重试')
-    }
-  }
-
-  static async getInfo (ctx) {
-    const theUser = getTokenUser(ctx)
-    if (!theUser) {
-      ctx.status = 401
-    } else {
-      const id = theUser.id
-      const user = await userModel.findByUid(id)
-      if (user) {
-        ctx.body = Response.success({ phone: user.phone, email: user.email, id: user.id, name: user.name, signature: user.signature })
-      } else {
-        ctx.body = Response.failed('用户信息获取失败')
-      }
-    }
-  }
-
-  static async saveName (ctx) {
-    const theUser = getTokenUser(ctx)
-    if (!theUser) {
-      ctx.status = 401
-    } else {
-      const id = theUser.id
-      const newName = ctx.request.body.newName
-      const result = await userModel.updateName(id, newName)
-      if (result.code === 0) {
-        ctx.body = Response.success({})
-      } else {
-        ctx.body = Response.failed('此昵称已被占用')
-      }
-    }
-  }
-
-  static async saveEmail (ctx) {
-    const theUser = await getTokenUser(ctx)
-    if (!theUser) {
-      ctx.status = 401
-    } else {
-      const id = theUser.id
-      const newEmail = ctx.request.body.newEmail
-
-      const myReg = /^[a-zA-Z0-9_-]+@([a-zA-Z0-9]+\.)+(com|cn|net|org)$/
-
-      if (!myReg.test(newEmail)) {
-        ctx.body = Response.failed('邮箱格式有误')
-      } else {
-        const result = await userModel.updateEmail(id, newEmail)
-        if (result.code === 0) {
-          ctx.body = Response.success({})
-        } else {
-          ctx.body = Response.failed('修改失败')
-        }
-      }
-    }
-  }
-
-  static async saveSignature (ctx) {
-    const theUser = await getTokenUser(ctx)
-    if (!theUser) {
-      ctx.status = 401
-    } else {
-      const id = theUser.id
-      const newSignature = ctx.request.body.newSignature
-
-      if (newSignature === 0) {
-        ctx.body = Response.failed('个性签名不得为空')
-      } else if (newSignature > 20) {
-        ctx.body = Response.failed('个性签名过长')
-      } else {
-        const result = await userModel.updateSignature(id, newSignature)
-        if (result.code === 0) {
-          ctx.body = Response.success({})
-        } else {
-          ctx.body = Response.failed('修改失败')
-        }
-      }
-    }
-  }
-
-  static async resetPassword (ctx) {
-    const data = ctx.request.body
-
-    if (!ctx.session.verification_phone || !ctx.session.verification_code) {
-      ctx.body = Response.failed('请重新获取验证码')
-    } else if (ctx.session.verification_code !== data.identifyCode || ctx.session.verification_phone !== data.phone) {
-      ctx.body = Response.failed('验证码错误')
-    } else if (data.password.length < 6 || data.password.length > 20 || data.phone.length !== 11) {
-      ctx.body = Response.failed('参数非法')
-    } else {
-      const hashPassword = bcrypt.hashSync(data.password, 10)
-      const result = await userModel.resetPassword(data.phone, hashPassword)
-      ctx.session.verification_phone = undefined
-      ctx.session.verification_code = undefined
-      if (result) {
-        ctx.body = Response.success({})
-      } else {
-        ctx.body = Response.failed('此手机号未注册')
-      }
-    }
-  }
-
-  /**
-   * 手机号搜id
-   */
-  static async findIdByPhone (ctx) {
-    const phone = ctx.params.phone
-    const user = await userModel.findByPhone(phone)
-    if (user) {
-      ctx.body = Response.success({ id: user.id })
-    } else {
-      ctx.body = Response.failed('此手机号未注册')
-    }
-  }
-}
-
-module.exports = UserController

+ 0 - 140
server/index.js

@@ -1,140 +0,0 @@
-const Koa = require('koa')
-const app = new Koa()
-const views = require('koa-views')
-const json = require('koa-json')
-const onerror = require('koa-onerror')
-const bodyparser = require('koa-bodyparser')
-const logger = require('koa-logger')
-const cors = require('koa2-cors')
-const jwt = require('koa-jwt')
-const session = require('koa-session')
-const consola = require('consola')
-const { Nuxt, Builder } = require('nuxt')
-const router = require('./routes/index')
-
-const { PORT = 3000, ISSUER = `http://localhost:${PORT}` } = process.env
-
-// error handler
-onerror(app)
-
-// middlewares
-app.use(bodyparser({
-  enableTypes: ['json', 'form', 'text']
-}))
-
-app.keys = ['seec']
-
-const CONFIG = {
-  key: 'SEEC', /** (string) cookie key (default is koa:sess) */
-  /** (number || 'session') maxAge in ms (default is 1 days) */
-  /** 'session' will result in a cookie that expires when session/browser is closed */
-  /** Warning: If a session cookie is stolen, this cookie will never expire */
-  maxAge: 5 * 60 * 1000,
-  overwrite: true, /** (boolean) can overwrite or not (default true) */
-  httpOnly: true, /** (boolean) httpOnly or not (default true) */
-  signed: true, /** (boolean) signed or not (default true) */
-  rolling: false /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. default is false **/
-}
-app.use(session(CONFIG, app))
-
-app.use(cors({
-  origin: (ctx) => {
-    return '*'
-  },
-  // exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
-  maxAge: 3600,
-  credentials: true,
-  allowMethods: ['GET', 'POST', 'OPTIONS'],
-  allowHeaders: ['Content-Type', 'Authorization', 'Accept']
-}))
-
-app.use(json())
-app.use(logger())
-app.use(require('koa-static')(__dirname + '/public'))
-
-app.use(views(__dirname + '/views', {
-  extension: 'ejs'
-}))
-
-// logger
-app.use(async (ctx, next) => {
-  const start = new Date()
-  await next()
-  const ms = new Date() - start
-  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
-})
-
-// Custom 401 handling if you don't want to expose koa-jwt errors to users
-app.use(function (ctx, next) {
-  return next().catch((err) => {
-    if (err.status === 401) {
-      ctx.status = 401
-      ctx.body = 'Protected resource, use Authorization header to get access\n'
-    } else {
-      throw err
-    }
-  })
-})
-//
-
-// error-handling
-app.on('error', (err, ctx) => {
-  console.error('server error', err, ctx)
-})
-
-// Import and Set Nuxt.js options
-const config = require('../nuxt.config.js')
-config.dev = app.env !== 'production'
-
-async function start () {
-  // Instantiate nuxt.js
-  const nuxt = new Nuxt(config)
-
-  const {
-    host = process.env.HOST || '127.0.0.1',
-    port = process.env.PORT || 3000
-  } = nuxt.options.server
-
-  await nuxt.ready()
-  // Build in development
-  if (config.dev) {
-    const builder = new Builder(nuxt)
-    await builder.build()
-  }
-
-  app.use(jwt({ secret: 'SEEC-1919810-OIDC-114514' }).unless({
-    // 设置login、register接口,可以不需要认证访问
-    path: [
-      /\/api\/user\/login/,
-      /\/api\/user\/register/,
-      /\/api\/user\/sendMessage/,
-      /\/api\/user\/resetPassword/,
-      /\/api\/user\/findIdByPhone/,
-      /\/api\/interaction/,
-      /\/api\/receiveIDToken/,
-      /\/api\/authenticate/,
-      /^((?!\/api).)*$/ // 设置除了私有接口外的其它资源,可以不需要认证访问
-    ]
-  }))
-
-  // routes
-  app.use(router().routes(), router().allowedMethods())
-
-  app.use((ctx) => {
-    ctx.req.session = ctx.session
-    ctx.status = 200
-    ctx.respond = false // Bypass Koa's built-in response handling
-    ctx.req.ctx = ctx // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash
-    nuxt.render(ctx.req, ctx.res)
-  })
-
-  app.listen(port, host)
-  consola.ready({
-    message: `Server listening on http://${host}:${port}`,
-    badge: true
-  })
-}
-
-start()
-
-// module.exports = app;

+ 0 - 55
server/model/teacher.js

@@ -1,55 +0,0 @@
-const db = require('../config/db')
-const getNowFormatTime = require('../util/time-processer')
-const Teacher = db.import('../schema/teacher.js')
-
-Teacher.sync()
-
-class TeacherModel {
-  static async findByUid (uid) {
-    return Teacher.findOne({
-      where: { uid: uid }
-    })
-  }
-
-  static async create ({ realName, organization, jobNumber, certificate = '', id, phone, email }) {
-    try {
-      await Teacher.create({
-        realName: realName,
-        organization: organization,
-        jobNumber: jobNumber,
-        phone: phone,
-        email: email,
-        certificate: certificate,
-        uid: id,
-        createdTime: getNowFormatTime()
-      })
-      return true
-    } catch (e) {
-      console.log(e)
-      return false
-    }
-  }
-
-  static async updateInfo ({ realName, organization, jobNumber, certificate = '', uid }) {
-    try {
-      await Teacher.update({ realName: realName, organization: organization, jobNumber: jobNumber, state: 'identifying' }, { where: { uid: uid } })
-      return true
-    } catch (e) {
-      console.log(e)
-      return false
-    }
-  }
-
-  static async updateState (id, state) {
-    await Teacher.update({ state: state }, { where: { id: id } })
-    return true
-  }
-
-  static async getApplications () {
-    return Teacher.findAll({
-      where: { state: 'identifying' }
-    })
-  }
-}
-
-module.exports = TeacherModel

+ 0 - 95
server/model/user.js

@@ -1,95 +0,0 @@
-const db = require('../config/db')
-const getNowFormatTime = require('../util/time-processer')
-const User = db.import('../schema/user.js')
-const seq = require('sequelize')
-const Op = seq.Op
-
-User.sync()
-
-class UserModel {
-  /**
-     * 按手机号码查询
-     * @param phone
-     * @returns {Promise.<*>}
-     */
-  static async findByPhone (phone) {
-    return User.findOne({
-      where: { phone: phone }
-    })
-  }
-
-  /**
-     * 创建用户
-     * @param name 昵称
-     * @param password 密码
-     * @param phone 手机号码
-     * @returns {Promise.<*>}
-     */
-  static async create (name, password, phone, email) {
-    let user = await User.findOne({
-      where: { phone: phone }
-    })
-    if (user) {
-      return { code: -2 }
-    }
-    user = await User.findOne({
-      where: { name: name }
-    })
-    if (user) {
-      return { code: -1 }
-    }
-    user = await User.create({ name: name, password: password, phone: phone, email: email, createdTime: getNowFormatTime() })
-    return { code: 0, data: user }
-  }
-
-  static async findByUid (id) {
-    return User.findOne({
-      where: { id: id }
-    })
-  }
-
-  static async updateName (id, newName) {
-    const user = await User.findOne({
-      where: { name: newName }
-    })
-    if (user) {
-      return { code: -1 }
-    }
-
-    await User.update({ name: newName }, { where: { id: id } })
-    return { code: 0 }
-  }
-
-  static async updateEmail (id, newEmail) {
-    await User.update({ email: newEmail }, { where: { id: id } })
-    return { code: 0 }
-  }
-
-  static async updateSignature (id, newSignature) {
-    await User.update({ signature: newSignature }, { where: { id: id } })
-    return { code: 0 }
-  }
-
-  static async identifyTeacher (uid) {
-    await User.update({ role: 'TEACHER' }, { where: { id: uid } })
-    return true
-  }
-
-  static async resetPassword (phone, newPassword) {
-    const result = await User.update({ password: newPassword }, { where: { phone: phone } })
-    return result[0] > 0
-  }
-
-  static async getUsers () {
-    return User.findAll({
-      where: { role: { [Op.ne]: 'ADMIN' } }
-    })
-  }
-
-  static async updateIsValid (id, isValid) {
-    await User.update({ isValid: isValid }, { where: { id: id } })
-    return true
-  }
-}
-
-module.exports = UserModel

+ 0 - 43
server/package.json

@@ -1,43 +0,0 @@
-{
-  "name": "portal-backend",
-  "version": "0.1.0",
-  "private": true,
-  "scripts": {
-    "start": "node bin/www",
-    "dev": "./node_modules/.bin/nodemon bin/www",
-    "prd": "pm2 start bin/www",
-    "test": "mocha --compilers js:babel-core/register"
-  },
-  "dependencies": {
-    "bcrypt": "^3.0.8",
-    "debug": "^4.1.1",
-    "koa": "^2.7.0",
-    "koa-bodyparser": "^4.2.1",
-    "koa-convert": "^1.2.0",
-    "koa-helmet": "^5.2.0",
-    "koa-json": "^2.0.2",
-    "koa-jwt": "^3.6.0",
-    "koa-logger": "^3.2.0",
-    "koa-mount": "^4.0.0",
-    "koa-onerror": "^4.1.0",
-    "koa-router": "^7.4.0",
-    "koa-static": "^5.0.0",
-    "koa-views": "^6.2.0",
-    "koa2-cors": "^2.0.6",
-    "lodash": "^4.17.15",
-    "mysql": "^2.18.1",
-    "mysql2": "^2.1.0",
-    "oidc-provider": "^6.23.1",
-    "openid-client": "^3.14.0",
-    "pug": "^2.0.3",
-    "request": "^2.88.2",
-    "sequelize": "^5.21.4",
-    "util": "^0.12.1"
-  },
-  "devDependencies": {
-    "nodemon": "^1.19.1",
-    "chai": "^4.2.0",
-    "supertest": "^4.0.2",
-    "mocha": "^7.0.1"
-  }
-}

+ 0 - 8
server/public/stylesheets/style.css

@@ -1,8 +0,0 @@
-body {
-  padding: 50px;
-  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
-}
-
-a {
-  color: #00B7FF;
-}

+ 0 - 40
server/routes/index.js

@@ -1,40 +0,0 @@
-const Router = require('koa-router')
-const UserController = require('../controller/user')
-const CourseController = require('../controller/course')
-const AuthController = require('../controller/auth')
-const TeacherController = require('../controller/teacher')
-const AdminController = require('../controller/admin')
-const router = new Router({ prefix: '/api' })
-
-module.exports = () => {
-  router.post('/user/login', UserController.login) // 登录
-  router.post('/user/register', UserController.register)
-  router.post('/user/sendMessage', UserController.sendMessage)
-  router.get('/user/getInfo', UserController.getInfo)
-  router.post('/user/saveName', UserController.saveName)
-  router.post('/user/saveEmail', UserController.saveEmail)
-  router.post('/user/saveSignature', UserController.saveSignature)
-  router.post('/user/resetPassword', UserController.resetPassword)
-  router.get('/user/findIdByPhone/:phone', UserController.findIdByPhone)
-
-  router.get('/teacher/getInfo', TeacherController.getInfo)
-  router.post('/teacher/apply', TeacherController.apply)
-  router.post('/teacher/reapply', TeacherController.reapply)
-
-  router.get('/admin/getApplications', AdminController.getApplications)
-  router.post('/admin/passApplication', AdminController.passApplication)
-  router.post('/admin/rejectApplication', AdminController.rejectApplication)
-  router.get('/admin/users', AdminController.getUsers)
-  router.put('/admin/user', AdminController.updateUser)
-
-  router.get('/course/getMyCourses', CourseController.getMyCourses)
-  router.get('/course/getHotCourses', CourseController.getHotCourses)
-
-  router.get('/interaction', AuthController.checkClient)
-  router.get('/receiveIDToken', AuthController.processIDToken)
-  router.get('/authenticate', AuthController.authenticate)
-
-  // 用户信息
-  // .post('/user/get', UserController.get); // 获取用户信息
-  return router
-}

+ 0 - 60
server/schema/teacher.js

@@ -1,60 +0,0 @@
-
-const moment = require('moment')
-
-module.exports = (sequelize, DataTypes) =>
-  sequelize.define('user', {
-    id: {
-      type: DataTypes.INTEGER,
-      allowNull: false,
-      primaryKey: true,
-      autoIncrement: true
-    },
-    realName: {
-      type: DataTypes.STRING(64),
-      allowNull: false
-    },
-    organization: {
-      type: DataTypes.STRING(64),
-      allowNull: false,
-      defaultValue: '南京大学'
-    },
-    jobNumber: {
-      type: DataTypes.STRING(64),
-      allowNull: false
-    },
-    certificate: {
-      type: DataTypes.STRING(512),
-      allowNull: false,
-      defaultValue: ''
-    },
-    phone: {
-      type: DataTypes.STRING(64),
-      allowNull: false,
-      unique: 'column'
-    },
-    email: {
-      type: DataTypes.STRING(512),
-      allowNull: false,
-      defaultValue: 'xxxxx@xxx.com'
-    },
-    uid: {
-      type: DataTypes.INTEGER,
-      allowNull: false,
-      unique: 'column'
-    },
-    createdTime: {
-      type: DataTypes.DATE,
-      allowNull: false,
-      get () {
-        return moment(this.getDataValue('createdTime')).format('YYYY-MM-DD HH:mm:ss')
-      }
-    },
-    state: {
-      type: DataTypes.ENUM,
-      values: ['identifying', 'identified', 'rejected'],
-      allowNull: false,
-      defaultValue: 'identifying'
-    }
-  }, {
-    tableName: 'teacher'
-  })

+ 0 - 62
server/schema/user.js

@@ -1,62 +0,0 @@
-
-const moment = require('moment')
-
-module.exports = (sequelize, DataTypes) =>
-  sequelize.define('user', {
-    id: {
-      type: DataTypes.INTEGER,
-      allowNull: false,
-      primaryKey: true,
-      autoIncrement: true
-    },
-    name: {
-      type: DataTypes.STRING(64),
-      allowNull: false,
-      unique: 'column'
-    },
-    password: {
-      type: DataTypes.STRING(512),
-      allowNull: false
-    },
-    phone: {
-      type: DataTypes.STRING(64),
-      allowNull: false,
-      unique: 'column'
-    },
-    email: {
-      type: DataTypes.STRING(512),
-      allowNull: false,
-      defaultValue: 'xxxxx@xxx.com'
-    },
-    photo: {
-      type: DataTypes.STRING(512),
-      allowNull: false,
-      defaultValue: '/image/default-photo.jpg'
-    },
-    role: {
-      type: DataTypes.ENUM,
-      values: ['STUDENT', 'TEACHER', 'ADMIN'],
-      allowNull: false,
-      defaultValue: 'STUDENT'
-    },
-    signature: {
-      type: DataTypes.STRING(512),
-      allowNull: false,
-      defaultValue: '无'
-    },
-    createdTime: {
-      type: DataTypes.DATE,
-      allowNull: false,
-      get () {
-        return moment(this.getDataValue('createdTime')).format('YYYY-MM-DD HH:mm:ss')
-      }
-
-    },
-    isValid: {
-      type: DataTypes.BOOLEAN,
-      allowNull: false,
-      defaultValue: true
-    }
-  }, {
-    tableName: 'user'
-  })

+ 0 - 90
server/support/account.js

@@ -1,90 +0,0 @@
-const store = new Map()
-const logins = new Map()
-const nanoid = require('nanoid')
-
-class Account {
-  constructor (id, profile) {
-    this.accountId = id || nanoid()
-    this.profile = profile
-    store.set(this.accountId, this)
-  }
-
-  /**
-   * @param use - can either be "id_token" or "userinfo", depending on
-   *   where the specific claims are intended to be put in.
-   * @param scope - the intended scope, while oidc-provider will mask
-   *   claims depending on the scope automatically you might want to skip
-   *   loading some claims from external resources etc. based on this detail
-   *   or not return them in id tokens but only userinfo and so on.
-   */
-  async claims (use, scope) { // eslint-disable-line no-unused-vars
-    if (this.profile) {
-      return {
-        sub: this.accountId, // it is essential to always return a sub claim
-        email: this.profile.email,
-        email_verified: this.profile.email_verified,
-        family_name: this.profile.family_name,
-        given_name: this.profile.given_name,
-        locale: this.profile.locale,
-        name: this.profile.name
-      }
-    }
-
-    return {
-      sub: this.accountId, // it is essential to always return a sub claim
-
-      address: {
-        country: '000',
-        formatted: '000',
-        locality: '000',
-        postal_code: '000',
-        region: '000',
-        street_address: '000'
-      },
-      birthdate: '1987-10-16',
-      email: 'johndoe@example.com',
-      email_verified: false,
-      family_name: 'Doe',
-      gender: 'male',
-      given_name: 'John',
-      locale: 'en-US',
-      middle_name: 'Middle',
-      name: 'John Doe',
-      nickname: 'Johny',
-      phone_number: '+49 000 000000',
-      phone_number_verified: false,
-      picture: 'http://lorempixel.com/400/200/',
-      preferred_username: 'johnny',
-      profile: 'https://johnswebsite.com',
-      updated_at: 1454704946,
-      website: 'http://example.com',
-      zoneinfo: 'Europe/Berlin'
-    }
-  }
-
-  static async findByFederated (provider, claims) {
-    const id = `${provider}.${claims.sub}`
-    if (!logins.get(id)) {
-      logins.set(id, new Account(id, claims))
-    }
-    return logins.get(id)
-  }
-
-  static async findByLogin (login) {
-    if (!logins.get(login)) {
-      logins.set(login, new Account(login))
-    }
-
-    return logins.get(login)
-  }
-
-  static async findAccount (ctx, id, token) { // eslint-disable-line no-unused-vars
-    // token is a reference to the token used for which a given account is being loaded,
-    //   it is undefined in scenarios where account claims are returned from authorization endpoint
-    // ctx is the koa request context
-    if (!store.get(id)) new Account(id) // eslint-disable-line no-new
-    return store.get(id)
-  }
-}
-
-module.exports = Account

+ 0 - 80
server/support/configuration.js

@@ -1,80 +0,0 @@
-const { interactionPolicy: { Prompt, base: policy } } = require('oidc-provider')
-
-// copies the default policy, already has login and consent prompt policies
-const interactions = policy()
-
-// create a requestable prompt with no implicit checks
-const selectAccount = new Prompt({
-  name: 'select_account',
-  requestable: true
-})
-
-// add to index 0, order goes select_account > login > consent
-interactions.add(selectAccount, 0)
-
-module.exports = {
-  clients: [
-    {
-      client_id: 'seec-portal-1919810-114514',
-      response_types: ['id_token'],
-      grant_types: ['implicit'],
-      token_endpoint_auth_method: 'none'
-    }
-  ],
-  interactions: {
-    // policy: interactions,
-    url: (ctx, interaction) => { // eslint-disable-line no-unused-vars
-      console.log('redirect now!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
-      return '/api/authenticate'
-    }
-  },
-  cookies: {
-    long: { signed: true, maxAge: (1 * 24 * 60 * 60) * 1000 }, // 1 day in ms
-    short: { signed: true, sameSite: 'none' },
-    keys: ['some secret key', 'and also the old rotated away some time ago', 'and one more']
-  },
-  claims: {
-    address: ['address'],
-    email: ['email', 'email_verified'],
-    phone: ['phone_number', 'phone_number_verified'],
-    profile: ['birthdate', 'family_name', 'gender', 'given_name', 'locale', 'middle_name', 'name',
-      'nickname', 'picture', 'preferred_username', 'profile', 'updated_at', 'website', 'zoneinfo']
-  },
-  features: {
-    devInteractions: { enabled: false }, // defaults to true
-
-    deviceFlow: { enabled: true }, // defaults to false
-    introspection: { enabled: true }, // defaults to false
-    revocation: { enabled: true } // defaults to false
-  },
-  jwks: {
-    keys: [
-      {
-        d: 'VEZOsY07JTFzGTqv6cC2Y32vsfChind2I_TTuvV225_-0zrSej3XLRg8iE_u0-3GSgiGi4WImmTwmEgLo4Qp3uEcxCYbt4NMJC7fwT2i3dfRZjtZ4yJwFl0SIj8TgfQ8ptwZbFZUlcHGXZIr4nL8GXyQT0CK8wy4COfmymHrrUoyfZA154ql_OsoiupSUCRcKVvZj2JHL2KILsq_sh_l7g2dqAN8D7jYfJ58MkqlknBMa2-zi5I0-1JUOwztVNml_zGrp27UbEU60RqV3GHjoqwI6m01U7K0a8Q_SQAKYGqgepbAYOA-P4_TLl5KC4-WWBZu_rVfwgSENwWNEhw8oQ',
-        dp: 'E1Y-SN4bQqX7kP-bNgZ_gEv-pixJ5F_EGocHKfS56jtzRqQdTurrk4jIVpI-ZITA88lWAHxjD-OaoJUh9Jupd_lwD5Si80PyVxOMI2xaGQiF0lbKJfD38Sh8frRpgelZVaK_gm834B6SLfxKdNsP04DsJqGKktODF_fZeaGFPH0',
-        dq: 'F90JPxevQYOlAgEH0TUt1-3_hyxY6cfPRU2HQBaahyWrtCWpaOzenKZnvGFZdg-BuLVKjCchq3G_70OLE-XDP_ol0UTJmDTT-WyuJQdEMpt_WFF9yJGoeIu8yohfeLatU-67ukjghJ0s9CBzNE_LrGEV6Cup3FXywpSYZAV3iqc',
-        e: 'AQAB',
-        kty: 'RSA',
-        n: 'xwQ72P9z9OYshiQ-ntDYaPnnfwG6u9JAdLMZ5o0dmjlcyrvwQRdoFIKPnO65Q8mh6F_LDSxjxa2Yzo_wdjhbPZLjfUJXgCzm54cClXzT5twzo7lzoAfaJlkTsoZc2HFWqmcri0BuzmTFLZx2Q7wYBm0pXHmQKF0V-C1O6NWfd4mfBhbM-I1tHYSpAMgarSm22WDMDx-WWI7TEzy2QhaBVaENW9BKaKkJklocAZCxk18WhR0fckIGiWiSM5FcU1PY2jfGsTmX505Ub7P5Dz75Ygqrutd5tFrcqyPAtPTFDk8X1InxkkUwpP3nFU5o50DGhwQolGYKPGtQ-ZtmbOfcWQ',
-        p: '5wC6nY6Ev5FqcLPCqn9fC6R9KUuBej6NaAVOKW7GXiOJAq2WrileGKfMc9kIny20zW3uWkRLm-O-3Yzze1zFpxmqvsvCxZ5ERVZ6leiNXSu3tez71ZZwp0O9gys4knjrI-9w46l_vFuRtjL6XEeFfHEZFaNJpz-lcnb3w0okrbM',
-        q: '3I1qeEDslZFB8iNfpKAdWtz_Wzm6-jayT_V6aIvhvMj5mnU-Xpj75zLPQSGa9wunMlOoZW9w1wDO1FVuDhwzeOJaTm-Ds0MezeC4U6nVGyyDHb4CUA3ml2tzt4yLrqGYMT7XbADSvuWYADHw79OFjEi4T3s3tJymhaBvy1ulv8M',
-        qi: 'wSbXte9PcPtr788e713KHQ4waE26CzoXx-JNOgN0iqJMN6C4_XJEX-cSvCZDf4rh7xpXN6SGLVd5ibIyDJi7bbi5EQ5AXjazPbLBjRthcGXsIuZ3AtQyR0CEWNSdM7EyM5TRdyZQ9kftfz9nI03guW3iKKASETqX2vh0Z8XRjyU',
-        use: 'sig'
-      }, {
-        crv: 'P-256',
-        d: 'K9xfPv773dZR22TVUB80xouzdF7qCg5cWjPjkHyv7Ws',
-        kty: 'EC',
-        use: 'sig',
-        x: 'FWZ9rSkLt6Dx9E3pxLybhdM6xgR5obGsj5_pqmnz5J4',
-        y: '_n8G69C-A2Xl4xUW2lF0i8ZGZnk_KPYrhv4GbTGu5G4'
-      }
-    ]
-  },
-  ttl: {
-    AccessToken: 1 * 60 * 60, // 1 hour in seconds
-    AuthorizationCode: 10 * 60, // 10 minutes in seconds
-    IdToken: 1 * 60 * 60, // 1 hour in seconds
-    DeviceCode: 10 * 60, // 10 minutes in seconds
-    RefreshToken: 1 * 24 * 60 * 60 // 1 day in seconds
-  }
-}

+ 0 - 27
server/test/course.test.js

@@ -1,27 +0,0 @@
-const supertest = require('supertest')
-const chai = require('chai')
-const util = require('util')
-const app = require('./../app')
-
-const expect = chai.expect
-const request = supertest(app.listen())
-
-describe('开始测试课程功能', () => {
-  let response
-  it('测试 /api/course/getHotCourses 请求', done => {
-    request
-      .get('/api/course/getHotCourses')
-      .send({})
-      .expect(200)
-      .end((err, res) => {
-        response = res
-        expect(res.body).to.be.an('object')
-        expect(res.body.code).to.eql(0)
-        done()
-      })
-  })
-
-  afterEach(function () {
-    console.log('    Response body: ' + util.inspect(response.body, { depth: null, colors: true }) + '\n')
-  })
-})

+ 0 - 67
server/test/user.test.js

@@ -1,67 +0,0 @@
-const supertest = require('supertest')
-const chai = require('chai')
-const util = require('util')
-const app = require('./../app')
-
-const expect = chai.expect
-const request = supertest(app.listen())
-
-describe('开始测试用户功能', () => {
-  let response
-  it('测试 /api/user/register 请求', done => {
-    request
-      .post('/api/user/register')
-      .send({ name: 'test', password: '123456', phone: '12345678912' })
-      .expect(200)
-      .end((err, res) => {
-        response = res
-        expect(res.body).to.be.an('object')
-        expect(res.body.code).to.eql(-1)
-        expect(res.body.message).to.eql('此手机号已注册')
-        done()
-      })
-  })
-  it('测试 /api/user/login 请求,正常登陆情况', done => {
-    request
-      .post('/api/user/login')
-      .send({ password: '123456', phone: '12345678912' })
-      .expect(200)
-      .end((err, res) => {
-        response = res
-        expect(res.body).to.be.an('object')
-        expect(res.body.code).to.eql(0)
-        expect(res.body.data).to.be.an('object')
-        done()
-      })
-  })
-  it('测试 /api/user/login 请求,密码错误情况', done => {
-    request
-      .post('/api/user/login')
-      .send({ password: '12345', phone: '12345678912' })
-      .expect(200)
-      .end((err, res) => {
-        response = res
-        expect(res.body).to.be.an('object')
-        expect(res.body.code).to.eql(-1)
-        expect(res.body.message).to.eql('密码错误,请重试')
-        done()
-      })
-  })
-  it('测试 /api/user/login 请求,账户不存在情况', done => {
-    request
-      .post('/api/user/login')
-      .send({ password: '123456', phone: '12345678913' })
-      .expect(200)
-      .end((err, res) => {
-        response = res
-        expect(res.body).to.be.an('object')
-        expect(res.body.code).to.eql(-1)
-        expect(res.body.message).to.eql('此账号不存在')
-        done()
-      })
-  })
-  //
-  // afterEach(function(){
-  //         console.log("    Response body: " + util.inspect(response.body,{depth: null, colors: true}) + "\n");
-  // })
-})

+ 0 - 10
server/util/aliClient.js

@@ -1,10 +0,0 @@
-const RPCClient = require('@alicloud/pop-core').RPCClient
-
-const client = new RPCClient({
-  accessKeyId: 'LTAI4FiAXXyNfYJLweBXpKPx',
-  accessKeySecret: 'IBoC7KGkZHOvxZQIfQgp98ZY48AVjW',
-  endpoint: 'https://dysmsapi.aliyuncs.com',
-  apiVersion: '2017-05-25'
-})
-
-module.exports = client

+ 0 - 15
server/util/request.js

@@ -1,15 +0,0 @@
-const request = require('request')
-const util = require('util')
-const getPromise = util.promisify(request.get)
-
-module.exports = async function (url, data) {
-  const result = await getPromise({
-    url: url,
-    headers: {
-      Authorization: 'Basic cm9vdDpOSlU2N3NvZnR3YXJl'
-    }
-  })
-  // 可以加入 try catch 捕获异常  也可以加 .catch()
-  console.log('result', result)
-  return result
-}

+ 0 - 11
server/util/response.js

@@ -1,11 +0,0 @@
-class Response {
-  static success (data) {
-    return { code: 0, data: data }
-  }
-
-  static failed (message) {
-    return { code: -1, message: message }
-  }
-}
-
-module.exports = Response

+ 0 - 41
server/util/time-processer.js

@@ -1,41 +0,0 @@
-module.exports = function getNowFormatDate () {
-  const date = new Date()
-
-  const year = date.getFullYear() // 年 ,从 Date 对象以四位数字返回年份
-  let month = date.getMonth() + 1 // 月 ,从 Date 对象返回月份 (0 ~ 11) ,date.getMonth()比实际月份少 1 个月
-  let day = date.getDate() // 日 ,从 Date 对象返回一个月中的某一天 (1 ~ 31)
-
-  let hours = date.getHours() // 小时 ,返回 Date 对象的小时 (0 ~ 23)
-  let minutes = date.getMinutes() // 分钟 ,返回 Date 对象的分钟 (0 ~ 59)
-  let seconds = date.getSeconds() // 秒 ,返回 Date 对象的秒数 (0 ~ 59)
-
-  // 修改月份格式
-  if (month >= 1 && month <= 9) {
-    month = '0' + month
-  }
-
-  // 修改日期格式
-  if (day >= 0 && day <= 9) {
-    day = '0' + day
-  }
-
-  // 修改小时格式
-  if (hours >= 0 && hours <= 9) {
-    hours = '0' + hours
-  }
-
-  // 修改分钟格式
-  if (minutes >= 0 && minutes <= 9) {
-    minutes = '0' + minutes
-  }
-
-  // 修改秒格式
-  if (seconds >= 0 && seconds <= 9) {
-    seconds = '0' + seconds
-  }
-
-  // 获取当前系统时间  格式(yyyy-mm-dd hh:mm:ss)
-  const currentFormatDate = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
-
-  return currentFormatDate
-}

+ 0 - 11
server/util/tokenProcessor.js

@@ -1,11 +0,0 @@
-const jwt = require('jsonwebtoken')
-
-module.exports = function getTokenUser (ctx) {
-  const token = ctx.header.authorization.substr(7)
-  try {
-    const user = jwt.verify(token, 'SEEC-1919810-OIDC-114514')
-    return user
-  } catch (e) {
-    return null
-  }
-}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor