openlearn-next 0.2.2 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/AdminDirectoryView-Cai0cQqi.js +1 -0
- package/dist/assets/BatchPickerModal-CKQyeY6R.js +1 -0
- package/dist/assets/ClassesView-Cxgfcrx1.js +19 -0
- package/dist/assets/CloudDriveModal-DgDurUBT.js +1 -0
- package/dist/assets/ComputerLabView-CUCO2VIV.js +1 -0
- package/dist/assets/CourseManagement-DSCOjuIC.js +1 -0
- package/dist/assets/CourseWizardModal-B3QnFxvj.js +3 -0
- package/dist/assets/CoursewareHubPanel-CAaf22Qm.js +1 -0
- package/dist/assets/Dashboard-BnF7YAQi.js +8 -0
- package/dist/assets/ExportWeightModal-BlS2auLs.js +1 -0
- package/dist/assets/HelpTour-ZgEkRnin.js +1 -0
- package/dist/assets/HelpView-BP581QYZ.js +204 -0
- package/dist/assets/ImportLessonsModal-BZZRDBRU.js +1 -0
- package/dist/assets/ImportModal-mkWuDoAN.js +1 -0
- package/dist/assets/InteractiveCoursewareViewer-EIRNulEo.js +1 -0
- package/dist/assets/InteractiveWhiteboard-D360IHbP.js +102 -0
- package/dist/assets/LazyCourseware-qE4CY67E.js +1 -0
- package/dist/assets/LazyWhiteboard-B5JmqHZ5.js +2 -0
- package/dist/assets/LessonEditorView-C0czhtmf.js +1 -0
- package/dist/assets/LiveClassroomView-CrTY3jhP.js +1 -0
- package/dist/assets/NotificationDetailModal-dndFrE7p.js +1 -0
- package/dist/assets/PluginView-QS2b6nSF.js +65 -0
- package/dist/assets/ProcessLogsModal-8mVp07ic.js +1 -0
- package/dist/assets/QuizGeneratorModal-DpTFYbVJ.js +1 -0
- package/dist/assets/StudentAssignmentView-YxVJ5wkl.js +1 -0
- package/dist/assets/StudentLessonView-D1gYdLM1.js +1 -0
- package/dist/assets/StudentPreviewModal-CG8bgUeI.js +1 -0
- package/dist/assets/StudentView-CmSL3cDw.js +1 -0
- package/dist/assets/SystemResourceLibraryModal-Dnh7F5Vm.js +1 -0
- package/dist/assets/TeacherView-BqXb0izg.js +2 -0
- package/dist/assets/TimetableView-zce3okQn.js +6 -0
- package/dist/assets/index-BrEBeWAQ.js +14 -0
- package/dist/assets/index-BxA9vp--.js +129 -0
- package/dist/assets/index-CATki2cp.css +1 -0
- package/dist/assets/index-Cq_aKTfc.js +1 -0
- package/dist/assets/{index.es-D071ILbD.js → index.es-DZ6UeYE-.js} +2 -2
- package/dist/assets/vendor-charts-B7ViBL9w.js +71 -0
- package/dist/assets/vendor-icons-BvCtGbt1.js +8221 -0
- package/dist/assets/vendor-konva-CzxOmTv9.js +49 -0
- package/dist/assets/vendor-motion-Dz5URUo4.js +9 -0
- package/dist/assets/vendor-pdf-CVyNPGVr.js +191 -0
- package/dist/assets/{vendor-pptx-CJ3I-KT0.js → vendor-pptx-B0hlo0eh.js} +1 -1
- package/dist/assets/vendor-react-0Lg0vA-4.js +49 -0
- package/dist/assets/vendor-utils-4FcTwKPj.js +1 -0
- package/dist/index.html +2 -3
- package/dist/server.cjs +164 -46
- package/package.json +1 -1
- package/dist/assets/courseware-CL7gjXZj.js +0 -1
- package/dist/assets/index-4xDvXGZ_.js +0 -682
- package/dist/assets/index-CaJDJGky.css +0 -1
- package/dist/assets/vendor-html2canvas-B0tyYwQk.js +0 -22
- package/dist/assets/vendor-konva-GivUq6dt.js +0 -89
- package/dist/assets/whiteboard-Dp8tFXTO.js +0 -8343
- /package/dist/assets/{purify.es-V6uLfjnH.js → vendor-content-V6uLfjnH.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{R as O,g as A,c as re}from"./vendor-react-0Lg0vA-4.js";const ee=n=>{let r;const t=new Set,s=(u,e)=>{const o=typeof u=="function"?u(r):u;if(!Object.is(o,r)){const l=r;r=e??(typeof o!="object"||o===null)?o:Object.assign({},r,o),t.forEach(g=>g(r,l))}},i=()=>r,c={setState:s,getState:i,getInitialState:()=>y,subscribe:u=>(t.add(u),()=>t.delete(u))},y=r=n(s,i,c);return c},Xt=(n=>n?ee(n):ee),Jt=n=>n;function Qt(n,r=Jt){const t=O.useSyncExternalStore(n.subscribe,O.useCallback(()=>r(n.getState()),[n,r]),O.useCallback(()=>r(n.getInitialState()),[n,r]));return O.useDebugValue(t),t}const Yt=n=>{const r=Xt(n),t=s=>Qt(r,s);return Object.assign(t,r),t},li=(n=>Yt);function St(n){var r,t,s="";if(typeof n=="string"||typeof n=="number")s+=n;else if(typeof n=="object")if(Array.isArray(n)){var i=n.length;for(r=0;r<i;r++)n[r]&&(t=St(n[r]))&&(s&&(s+=" "),s+=t)}else for(t in n)n[t]&&(s&&(s+=" "),s+=t);return s}function gi(){for(var n,r,t=0,s="",i=arguments.length;t<i;t++)(n=arguments[t])&&(r=St(n))&&(s&&(s+=" "),s+=r);return s}var w={},x={},te;function vt(){if(te)return x;te=1;function n(r){return r==="__proto__"}return x.isUnsafeProperty=n,x}var j={},ne;function _(){if(ne)return j;ne=1;function n(r){switch(typeof r){case"number":case"symbol":return!1;case"string":return r.includes(".")||r.includes("[")||r.includes("]")}}return j.isDeepKey=n,j}var T={},ie;function S(){if(ie)return T;ie=1;function n(r){return typeof r=="string"||typeof r=="symbol"?r:Object.is(r?.valueOf?.(),-0)?"-0":String(r)}return T.toKey=n,T}var M={},L={},se;function Ct(){if(se)return L;se=1;function n(r){if(r==null)return"";if(typeof r=="string")return r;if(Array.isArray(r))return r.map(n).join(",");const t=String(r);return t==="0"&&Object.is(Number(r),-0)?"-0":t}return L.toString=n,L}var ue;function v(){if(ue)return M;ue=1;const n=S(),r=Ct();function t(s){if(Array.isArray(s))return s.map(n.toKey);if(typeof s=="symbol")return[s];s=r.toString(s);const i=[],a=s.length;if(a===0)return i;let f=0,c="",y="",u=!1;for(s.charCodeAt(0)===46&&(i.push(""),f++);f<a;){const e=s[f];y?e==="\\"&&f+1<a?(f++,c+=s[f]):e===y?y="":c+=e:u?e==='"'||e==="'"?y=e:e==="]"?(u=!1,i.push(c),c=""):c+=e:e==="["?(u=!0,c&&(i.push(c),c="")):e==="."?c&&(i.push(c),c=""):c+=e,f++}return c&&i.push(c),i}return M.toPath=t,M}var ae;function P(){if(ae)return w;ae=1;const n=vt(),r=_(),t=S(),s=v();function i(f,c,y){if(f==null)return y;switch(typeof c){case"string":{if(n.isUnsafeProperty(c))return y;const u=f[c];return u===void 0?r.isDeepKey(c)?i(f,s.toPath(c),y):y:u}case"number":case"symbol":{typeof c=="number"&&(c=t.toKey(c));const u=f[c];return u===void 0?y:u}default:{if(Array.isArray(c))return a(f,c,y);if(Object.is(c?.valueOf(),-0)?c="-0":c=String(c),n.isUnsafeProperty(c))return y;const u=f[c];return u===void 0?y:u}}}function a(f,c,y){if(c.length===0)return y;let u=f;for(let e=0;e<c.length;e++){if(u==null||n.isUnsafeProperty(c[e]))return y;u=u[c[e]]}return u===void 0?y:u}return w.get=i,w}var E,oe;function rn(){return oe||(oe=1,E=P().get),E}var en=rn();const qi=A(en);var W={},K={},fe;function tn(){if(fe)return K;fe=1;function n(r,t){const s=new Map;for(let i=0;i<r.length;i++){const a=r[i],f=t(a,i,r);s.has(f)||s.set(f,a)}return Array.from(s.values())}return K.uniqBy=n,K}var N={},ce;function nn(){if(ce)return N;ce=1;function n(r,t){return function(...s){return r.apply(this,s.slice(0,t))}}return N.ary=n,N}var U={},ye;function R(){if(ye)return U;ye=1;function n(r){return r}return U.identity=n,U}var k={},F={},le;function sn(){if(le)return F;le=1;const n=P();function r(t){return function(s){return n.get(s,t)}}return F.property=r,F}var G={},Z={},$={},V={},ge;function Pt(){if(ge)return V;ge=1;function n(r){return r==null||typeof r!="object"&&typeof r!="function"}return V.isPrimitive=n,V}var z={},qe;function Rt(){if(qe)return z;qe=1;function n(r){return ArrayBuffer.isView(r)&&!(r instanceof DataView)}return z.isTypedArray=n,z}var H={},he;function Dt(){if(he)return H;he=1;function n(r){return Object.getOwnPropertySymbols(r).filter(t=>Object.prototype.propertyIsEnumerable.call(r,t))}return H.getSymbols=n,H}var X={},me;function Cr(){if(me)return X;me=1;function n(r){return r==null?r===void 0?"[object Undefined]":"[object Null]":Object.prototype.toString.call(r)}return X.getTag=n,X}var p={},de;function wt(){if(de)return p;de=1;const n="[object RegExp]",r="[object String]",t="[object Number]",s="[object Boolean]",i="[object Arguments]",a="[object Symbol]",f="[object Date]",c="[object Map]",y="[object Set]",u="[object Array]",e="[object Function]",o="[object ArrayBuffer]",l="[object Object]",g="[object Error]",h="[object DataView]",m="[object Uint8Array]",q="[object Uint8ClampedArray]",d="[object Uint16Array]",b="[object Uint32Array]",I="[object BigUint64Array]",Ft="[object Int8Array]",Gt="[object Int16Array]",Zt="[object Int32Array]",Vt="[object BigInt64Array]",zt="[object Float32Array]",Ht="[object Float64Array]";return p.argumentsTag=i,p.arrayBufferTag=o,p.arrayTag=u,p.bigInt64ArrayTag=Vt,p.bigUint64ArrayTag=I,p.booleanTag=s,p.dataViewTag=h,p.dateTag=f,p.errorTag=g,p.float32ArrayTag=zt,p.float64ArrayTag=Ht,p.functionTag=e,p.int16ArrayTag=Gt,p.int32ArrayTag=Zt,p.int8ArrayTag=Ft,p.mapTag=c,p.numberTag=t,p.objectTag=l,p.regexpTag=n,p.setTag=y,p.stringTag=r,p.symbolTag=a,p.uint16ArrayTag=d,p.uint32ArrayTag=b,p.uint8ArrayTag=m,p.uint8ClampedArrayTag=q,p}var J={},Q={},pe;function un(){if(pe)return Q;pe=1;const n=typeof globalThis=="object"&&globalThis||typeof window=="object"&&window||typeof self=="object"&&self||typeof re=="object"&&re||(function(){return this})()||Function("return this")();return Q.globalThis_=n,Q}var be;function xt(){if(be)return J;be=1;const n=un();function r(t){return typeof n.globalThis_.Buffer<"u"&&n.globalThis_.Buffer.isBuffer(t)}return J.isBuffer=r,J}var Ae;function jt(){if(Ae)return $;Ae=1;const n=Pt(),r=Rt(),t=Dt(),s=Cr(),i=wt(),a=xt();function f(e,o){return c(e,void 0,e,new Map,o)}function c(e,o,l,g=new Map,h=void 0){const m=h?.(e,o,l,g);if(m!==void 0)return m;if(n.isPrimitive(e))return e;if(g.has(e))return g.get(e);if(Array.isArray(e)){const q=new Array(e.length);g.set(e,q);for(let d=0;d<e.length;d++)q[d]=c(e[d],d,l,g,h);return Object.hasOwn(e,"index")&&(q.index=e.index),Object.hasOwn(e,"input")&&(q.input=e.input),q}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp){const q=new RegExp(e.source,e.flags);return q.lastIndex=e.lastIndex,q}if(e instanceof Map){const q=new Map;g.set(e,q);for(const[d,b]of e)q.set(d,c(b,d,l,g,h));return q}if(e instanceof Set){const q=new Set;g.set(e,q);for(const d of e)q.add(c(d,void 0,l,g,h));return q}if(a.isBuffer(e))return e.subarray();if(r.isTypedArray(e)){const q=new(Object.getPrototypeOf(e)).constructor(e.length);g.set(e,q);for(let d=0;d<e.length;d++)q[d]=c(e[d],d,l,g,h);return q}if(e instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&e instanceof SharedArrayBuffer)return e.slice(0);if(e instanceof DataView){const q=new DataView(e.buffer.slice(0),e.byteOffset,e.byteLength);return g.set(e,q),y(q,e,l,g,h),q}if(typeof File<"u"&&e instanceof File){const q=new File([e],e.name,{type:e.type});return g.set(e,q),y(q,e,l,g,h),q}if(typeof Blob<"u"&&e instanceof Blob){const q=new Blob([e],{type:e.type});return g.set(e,q),y(q,e,l,g,h),q}if(e instanceof Error){const q=structuredClone(e);return g.set(e,q),q.message=e.message,q.name=e.name,q.stack=e.stack,q.cause=e.cause,q.constructor=e.constructor,y(q,e,l,g,h),q}if(e instanceof Boolean){const q=new Boolean(e.valueOf());return g.set(e,q),y(q,e,l,g,h),q}if(e instanceof Number){const q=new Number(e.valueOf());return g.set(e,q),y(q,e,l,g,h),q}if(e instanceof String){const q=new String(e.valueOf());return g.set(e,q),y(q,e,l,g,h),q}if(typeof e=="object"&&u(e)){const q=Object.create(Object.getPrototypeOf(e));return g.set(e,q),y(q,e,l,g,h),q}return e}function y(e,o,l=e,g,h){const m=[...Object.keys(o),...t.getSymbols(o)];for(let q=0;q<m.length;q++){const d=m[q],b=Object.getOwnPropertyDescriptor(e,d);(b==null||b.writable)&&(e[d]=c(o[d],d,l,g,h))}}function u(e){switch(s.getTag(e)){case i.argumentsTag:case i.arrayTag:case i.arrayBufferTag:case i.dataViewTag:case i.booleanTag:case i.dateTag:case i.float32ArrayTag:case i.float64ArrayTag:case i.int8ArrayTag:case i.int16ArrayTag:case i.int32ArrayTag:case i.mapTag:case i.numberTag:case i.objectTag:case i.regexpTag:case i.setTag:case i.stringTag:case i.symbolTag:case i.uint8ArrayTag:case i.uint8ClampedArrayTag:case i.uint16ArrayTag:case i.uint32ArrayTag:return!0;default:return!1}}return $.cloneDeepWith=f,$.cloneDeepWithImpl=c,$.copyProperties=y,$}var Ie;function an(){if(Ie)return Z;Ie=1;const n=jt();function r(t){return n.cloneDeepWithImpl(t,void 0,t,new Map,void 0)}return Z.cloneDeep=r,Z}var Y={},C={},rr={},$e;function Tt(){if($e)return rr;$e=1;function n(r,t){return r===t||Number.isNaN(r)&&Number.isNaN(t)}return rr.isEqualsSameValueZero=n,rr}var er={},Be;function Mt(){if(Be)return er;Be=1;function n(r){return r!==null&&(typeof r=="object"||typeof r=="function")}return er.isObject=n,er}var Oe;function on(){if(Oe)return C;Oe=1;const n=Pt(),r=Tt(),t=Mt();function s(u,e,o){return typeof o!="function"?s(u,e,()=>{}):i(u,e,function l(g,h,m,q,d,b){const I=o(g,h,m,q,d,b);return I!==void 0?!!I:i(g,h,l,b)},new Map)}function i(u,e,o,l){if(e===u)return!0;switch(typeof e){case"object":return a(u,e,o,l);case"function":return Object.keys(e).length>0?i(u,{...e},o,l):r.isEqualsSameValueZero(u,e);default:return t.isObject(u)?typeof e=="string"?e==="":!0:r.isEqualsSameValueZero(u,e)}}function a(u,e,o,l){if(e==null)return!0;if(Array.isArray(e))return c(u,e,o,l);if(e instanceof Map)return f(u,e,o,l);if(e instanceof Set)return y(u,e,o,l);const g=Object.keys(e);if(u==null||n.isPrimitive(u))return g.length===0;if(g.length===0)return!0;if(l?.has(e))return l.get(e)===u;l?.set(e,u);try{for(let h=0;h<g.length;h++){const m=g[h];if(!n.isPrimitive(u)&&!(m in u)||e[m]===void 0&&u[m]!==void 0||e[m]===null&&u[m]!==null||!o(u[m],e[m],m,u,e,l))return!1}return!0}finally{l?.delete(e)}}function f(u,e,o,l){if(e.size===0)return!0;if(!(u instanceof Map))return!1;for(const[g,h]of e.entries())if(o(u.get(g),h,g,u,e,l)===!1)return!1;return!0}function c(u,e,o,l){if(e.length===0)return!0;if(!Array.isArray(u))return!1;const g=new Set;for(let h=0;h<e.length;h++){const m=e[h];let q=!1;for(let d=0;d<u.length;d++){if(g.has(d))continue;const b=u[d];let I=!1;if(o(b,m,h,u,e,l)&&(I=!0),I){g.add(d),q=!0;break}}if(!q)return!1}return!0}function y(u,e,o,l){return e.size===0?!0:u instanceof Set?c([...u],[...e],o,l):!1}return C.isMatchWith=s,C}var _e;function Lt(){if(_e)return Y;_e=1;const n=on();function r(t,s){return n.isMatchWith(t,s,()=>{})}return Y.isMatch=r,Y}var Se;function fn(){if(Se)return G;Se=1;const n=an(),r=Lt();function t(s){return s=n.cloneDeep(s),i=>r.isMatch(i,s)}return G.matches=t,G}var tr={},nr={},ir={},ve;function Et(){if(ve)return ir;ve=1;const n=Cr(),r=wt(),t=jt();function s(i,a){return t.cloneDeepWith(i,(f,c,y,u)=>{const e=a?.(f,c,y,u);if(e!==void 0)return e;if(typeof i=="object"){if(n.getTag(i)==="[object Object]"&&typeof i.constructor!="function"){const o={};return u.set(i,o),t.copyProperties(o,i,y,u),o}switch(Object.prototype.toString.call(i)){case r.numberTag:case r.stringTag:case r.booleanTag:{const o=new i.constructor(i?.valueOf());return t.copyProperties(o,i),o}case r.argumentsTag:{const o={};return t.copyProperties(o,i),o.length=i.length,o[Symbol.iterator]=i[Symbol.iterator],o}default:return}}})}return ir.cloneDeepWith=s,ir}var Pe;function cn(){if(Pe)return nr;Pe=1;const n=Et();function r(t){return n.cloneDeepWith(t)}return nr.cloneDeep=r,nr}var sr={},ur={},Re;function Wt(){if(Re)return ur;Re=1;const n=/^(?:0|[1-9]\d*)$/;function r(t,s=Number.MAX_SAFE_INTEGER){switch(typeof t){case"number":return Number.isInteger(t)&&t>=0&&t<s;case"symbol":return!1;case"string":return n.test(t)}}return ur.isIndex=r,ur}var ar={},De;function yn(){if(De)return ar;De=1;const n=Cr();function r(t){return t!==null&&typeof t=="object"&&n.getTag(t)==="[object Arguments]"}return ar.isArguments=r,ar}var we;function ln(){if(we)return sr;we=1;const n=_(),r=v(),t=Wt(),s=yn();function i(a,f){let c;if(Array.isArray(f)?c=f:typeof f=="string"&&n.isDeepKey(f)&&a?.[f]==null?c=r.toPath(f):c=[f],c.length===0)return!1;let y=a;for(let u=0;u<c.length;u++){const e=c[u];if((y==null||!Object.hasOwn(y,e))&&!((Array.isArray(y)||s.isArguments(y))&&t.isIndex(e)&&e<y.length))return!1;y=y[e]}return!0}return sr.has=i,sr}var xe;function gn(){if(xe)return tr;xe=1;const n=S(),r=P(),t=Lt(),s=cn(),i=ln();function a(f,c){switch(typeof f){case"object":Object.is(f?.valueOf(),-0)&&(f="-0");break;case"number":f=n.toKey(f);break}return c=s.cloneDeep(c),function(y){const u=r.get(y,f);return u===void 0?i.has(y,f):c===void 0?u===void 0:t.isMatch(u,c)}}return tr.matchesProperty=a,tr}var je;function D(){if(je)return k;je=1;const n=R(),r=sn(),t=fn(),s=gn();function i(a){if(a==null)return n.identity;switch(typeof a){case"function":return a;case"object":return Array.isArray(a)&&a.length===2?s.matchesProperty(a[0],a[1]):t.matches(a);case"string":case"symbol":case"number":return r.property(a)}}return k.iteratee=i,k}var or={},fr={},cr={},Te;function qn(){if(Te)return cr;Te=1;function n(r){return Number.isSafeInteger(r)&&r>=0}return cr.isLength=n,cr}var Me;function B(){if(Me)return fr;Me=1;const n=qn();function r(t){return t!=null&&typeof t!="function"&&n.isLength(t.length)}return fr.isArrayLike=r,fr}var yr={},Le;function hn(){if(Le)return yr;Le=1;function n(r){return typeof r=="object"&&r!==null}return yr.isObjectLike=n,yr}var Ee;function mn(){if(Ee)return or;Ee=1;const n=B(),r=hn();function t(s){return r.isObjectLike(s)&&n.isArrayLike(s)}return or.isArrayLikeObject=t,or}var We;function dn(){if(We)return W;We=1;const n=tn(),r=nn(),t=R(),s=D(),i=mn();function a(f,c=t.identity){return i.isArrayLikeObject(f)?n.uniqBy(Array.from(f),r.ary(s.iteratee(c),1)):[]}return W.uniqBy=a,W}var lr,Ke;function pn(){return Ke||(Ke=1,lr=dn().uniqBy),lr}var bn=pn();const hi=A(bn);var gr={},qr={},Ne;function An(){if(Ne)return qr;Ne=1;function n(r,t=1){const s=[],i=Math.floor(t),a=(f,c)=>{for(let y=0;y<f.length;y++){const u=f[y];Array.isArray(u)&&c<i?a(u,c+1):s.push(u)}};return a(r,0),s}return qr.flatten=n,qr}var hr={},Ue;function Kt(){if(Ue)return hr;Ue=1;const n=Tt(),r=B(),t=Mt(),s=Wt();function i(a,f,c){return t.isObject(c)&&(typeof f=="number"&&r.isArrayLike(c)&&s.isIndex(f)&&f<c.length||typeof f=="string"&&f in c)?n.isEqualsSameValueZero(c[f],a):!1}return hr.isIterateeCall=i,hr}var mr={},dr={},ke;function In(){if(ke)return dr;ke=1;function n(t){return typeof t=="symbol"?1:t===null?2:t===void 0?3:t!==t?4:0}const r=(t,s,i)=>{if(t!==s){const a=n(t),f=n(s);if(a===f&&a===0){if(t<s)return i==="desc"?1:-1;if(t>s)return i==="desc"?-1:1}return i==="desc"?f-a:a-f}return 0};return dr.compareValues=r,dr}var pr={},br={},Fe;function Nt(){if(Fe)return br;Fe=1;function n(r){return typeof r=="symbol"||r instanceof Symbol}return br.isSymbol=n,br}var Ge;function $n(){if(Ge)return pr;Ge=1;const n=Nt(),r=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,t=/^\w*$/;function s(i,a){return Array.isArray(i)?!1:typeof i=="number"||typeof i=="boolean"||i==null||n.isSymbol(i)?!0:typeof i=="string"&&(t.test(i)||!r.test(i))||a!=null&&Object.hasOwn(a,i)}return pr.isKey=s,pr}var Ze;function Bn(){if(Ze)return mr;Ze=1;const n=v(),r=In(),t=$n();function s(i,a,f,c){if(i==null)return[];f=c?void 0:f,Array.isArray(i)||(i=Object.values(i)),Array.isArray(a)||(a=a==null?[null]:[a]),a.length===0&&(a=[null]),Array.isArray(f)||(f=f==null?[]:[f]),f=f.map(o=>String(o));const y=(o,l)=>{let g=o;for(let h=0;h<l.length&&g!=null;++h)g=g[l[h]];return g},u=(o,l)=>l==null||o==null?l:typeof o=="object"&&"key"in o?Object.hasOwn(l,o.key)?l[o.key]:y(l,o.path):typeof o=="function"?o(l):Array.isArray(o)?y(l,o):typeof l=="object"?l[o]:l,e=a.map(o=>(Array.isArray(o)&&o.length===1&&(o=o[0]),o==null||typeof o=="function"||Array.isArray(o)||t.isKey(o)?o:{key:o,path:n.toPath(o)}));return i.map(o=>({original:o,criteria:e.map(l=>u(l,o))})).slice().sort((o,l)=>{for(let g=0;g<e.length;g++){const h=r.compareValues(o.criteria[g],l.criteria[g],f[g]);if(h!==0)return h}return 0}).map(o=>o.original)}return mr.orderBy=s,mr}var Ve;function On(){if(Ve)return gr;Ve=1;const n=An(),r=Kt(),t=Bn();function s(i,...a){const f=a.length;return f>1&&r.isIterateeCall(i,a[0],a[1])?a=[]:f>2&&r.isIterateeCall(a[0],a[1],a[2])&&(a=[a[0]]),t.orderBy(i,n.flatten(a),["asc"])}return gr.sortBy=s,gr}var Ar,ze;function _n(){return ze||(ze=1,Ar=On().sortBy),Ar}var Sn=_n();const mi=A(Sn);var Ir={},$r={},Br={},He;function vn(){if(He)return Br;He=1;function n(r,t,{signal:s,edges:i}={}){let a,f=null;const c=i!=null&&i.includes("leading"),y=i==null||i.includes("trailing"),u=()=>{f!==null&&(r.apply(a,f),a=void 0,f=null)},e=()=>{y&&u(),h()};let o=null;const l=()=>{o!=null&&clearTimeout(o),o=setTimeout(()=>{o=null,e()},t)},g=()=>{o!==null&&(clearTimeout(o),o=null)},h=()=>{g(),a=void 0,f=null},m=()=>{u()},q=function(...d){if(s?.aborted)return;a=this,f=d;const b=o==null;l(),c&&b&&u()};return q.schedule=l,q.cancel=h,q.flush=m,s?.addEventListener("abort",h,{once:!0}),q}return Br.debounce=n,Br}var Xe;function Pn(){if(Xe)return $r;Xe=1;const n=vn();function r(t,s=0,i={}){typeof i!="object"&&(i={});const{leading:a=!1,trailing:f=!0,maxWait:c}=i,y=Array(2);a&&(y[0]="leading"),f&&(y[1]="trailing");let u,e=null;const o=n.debounce(function(...h){u=t.apply(this,h),e=null},s,{edges:y}),l=function(...h){return c!=null&&(e===null&&(e=Date.now()),Date.now()-e>=c)?(u=t.apply(this,h),e=Date.now(),o.cancel(),o.schedule(),u):(o.apply(this,h),u)},g=()=>(o.flush(),u);return l.cancel=o.cancel,l.flush=g,l}return $r.debounce=r,$r}var Je;function Rn(){if(Je)return Ir;Je=1;const n=Pn();function r(t,s=0,i={}){const{leading:a=!0,trailing:f=!0}=i;return n.debounce(t,s,{leading:a,maxWait:s,trailing:f})}return Ir.throttle=r,Ir}var Or,Qe;function Dn(){return Qe||(Qe=1,Or=Rn().throttle),Or}var wn=Dn();const di=A(wn);var _r={},Sr={},vr={},Ye;function xn(){if(Ye)return vr;Ye=1;const n=Nt();function r(t){return n.isSymbol(t)?NaN:Number(t)}return vr.toNumber=r,vr}var Ce;function Ut(){if(Ce)return Sr;Ce=1;const n=xn();function r(t){return t?(t=n.toNumber(t),t===1/0||t===-1/0?(t<0?-1:1)*Number.MAX_VALUE:t===t?t:0):t===0?t:0}return Sr.toFinite=r,Sr}var rt;function jn(){if(rt)return _r;rt=1;const n=Ut(),r=Kt();function t(s,i,a){a&&typeof a!="number"&&r.isIterateeCall(s,i,a)&&(i=a=void 0),s=n.toFinite(s),i===void 0?(i=s,s=0):i=n.toFinite(i),a=a===void 0?s<i?1:-1:n.toFinite(a);const f=Math.max(Math.ceil((i-s)/(a||1)),0),c=new Array(f);for(let y=0;y<f;y++)c[y]=s,s+=a;return c}return _r.range=t,_r}var Pr,et;function Tn(){return et||(et=1,Pr=jn().range),Pr}var Mn=Tn();const pi=A(Mn);var Rr={},Dr={},tt;function Ln(){if(tt)return Dr;tt=1;function n(r,t){if(r.length===0)return;let s=r[0],i=t(s,0,r);for(let a=1;a<r.length;a++){const f=r[a],c=t(f,a,r);c>i&&(i=c,s=f)}return s}return Dr.maxBy=n,Dr}var nt;function En(){if(nt)return Rr;nt=1;const n=Ln(),r=R(),t=D();function s(i,a){if(i!=null)return n.maxBy(Array.from(i),t.iteratee(a??r.identity))}return Rr.maxBy=s,Rr}var wr,it;function Wn(){return it||(it=1,wr=En().maxBy),wr}var Kn=Wn();const bi=A(Kn);var xr={},jr={},st;function Nn(){if(st)return jr;st=1;function n(r,t){if(r.length===0)return;let s=r[0],i=t(s,0,r);for(let a=1;a<r.length;a++){const f=r[a],c=t(f,a,r);c<i&&(i=c,s=f)}return s}return jr.minBy=n,jr}var ut;function Un(){if(ut)return xr;ut=1;const n=Nn(),r=R(),t=D();function s(i,a){if(i!=null)return n.minBy(Array.from(i),t.iteratee(a??r.identity))}return xr.minBy=s,xr}var Tr,at;function kn(){return at||(at=1,Tr=Un().minBy),Tr}var Fn=kn();const Ai=A(Fn);var Mr={},ot;function kt(){if(ot)return Mr;ot=1;function n(r){if(typeof r!="object"||r==null)return!1;if(Object.getPrototypeOf(r)===null)return!0;if(Object.prototype.toString.call(r)!=="[object Object]"){const s=r[Symbol.toStringTag];return s==null||!Object.getOwnPropertyDescriptor(r,Symbol.toStringTag)?.writable?!1:r.toString()===`[object ${s}]`}let t=r;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(r)===t}return Mr.isPlainObject=n,Mr}var Lr,ft;function Gn(){return ft||(ft=1,Lr=kt().isPlainObject),Lr}var Zn=Gn();const Ii=A(Zn);var Er={},Wr={},ct;function Vn(){if(ct)return Wr;ct=1;function n(r){return r[r.length-1]}return Wr.last=n,Wr}var Kr={},yt;function zn(){if(yt)return Kr;yt=1;function n(r){return Array.isArray(r)?r:Array.from(r)}return Kr.toArray=n,Kr}var lt;function Hn(){if(lt)return Er;lt=1;const n=Vn(),r=zn(),t=B();function s(i){if(t.isArrayLike(i))return n.last(r.toArray(i))}return Er.last=s,Er}var Nr,gt;function Xn(){return gt||(gt=1,Nr=Hn().last),Nr}var Jn=Xn();const $i=A(Jn);var Ur={},kr={},qt;function Qn(){if(qt)return kr;qt=1;const n=B();function r(t,s=1){const i=[],a=Math.floor(s);if(!n.isArrayLike(t))return i;const f=(c,y)=>{for(let u=0;u<c.length;u++){const e=c[u];y<a&&(Array.isArray(e)||e?.[Symbol.isConcatSpreadable]||e!==null&&typeof e=="object"&&Object.prototype.toString.call(e)==="[object Arguments]")?Array.isArray(e)?f(e,y+1):f(Array.from(e),y+1):i.push(e)}};return f(Array.from(t),0),i}return kr.flatten=r,kr}var Fr={},ht;function Yn(){if(ht)return Fr;ht=1;const n=vt(),r=_(),t=S(),s=v(),i=P();function a(c,y){if(c==null)return!0;switch(typeof y){case"symbol":case"number":case"object":if(Array.isArray(y))return f(c,y);if(typeof y=="number"?y=t.toKey(y):typeof y=="object"&&(Object.is(y?.valueOf(),-0)?y="-0":y=String(y)),n.isUnsafeProperty(y))return!1;if(c?.[y]===void 0)return!0;try{return delete c[y],!0}catch{return!1}case"string":if(c?.[y]===void 0&&r.isDeepKey(y))return f(c,s.toPath(y));if(n.isUnsafeProperty(y))return!1;try{return delete c[y],!0}catch{return!1}}}function f(c,y){const u=y.length===1?c:i.get(c,y.slice(0,-1)),e=y[y.length-1];if(u?.[e]===void 0)return!0;if(n.isUnsafeProperty(e))return!1;try{return delete u[e],!0}catch{return!1}}return Fr.unset=a,Fr}var Gr={},Zr={},mt;function Cn(){if(mt)return Zr;mt=1;function n(r){const t=r?.constructor;return r===(typeof t=="function"?t.prototype:Object.prototype)}return Zr.isPrototype=n,Zr}var Vr={},dt;function ri(){if(dt)return Vr;dt=1;const n=Rt();function r(t){return n.isTypedArray(t)}return Vr.isTypedArray=r,Vr}var zr={},Hr={},pt;function ei(){if(pt)return Hr;pt=1;const n=Ut();function r(t){const s=n.toFinite(t),i=s%1;return i?s-i:s}return Hr.toInteger=r,Hr}var bt;function ti(){if(bt)return zr;bt=1;const n=ei();function r(t,s){if(t=n.toInteger(t),t<1||!Number.isSafeInteger(t))return[];const i=new Array(t);for(let a=0;a<t;a++)i[a]=typeof s=="function"?s(a):a;return i}return zr.times=r,zr}var At;function ni(){if(At)return Gr;At=1;const n=xt(),r=B(),t=Cn(),s=ri(),i=ti();function a(u){if(u==null)return[];switch(typeof u){case"object":case"function":return r.isArrayLike(u)?y(u):t.isPrototype(u)?c(u):f(u);default:return f(Object(u))}}function f(u){const e=[];for(const o in u)e.push(o);return e}function c(u){return f(u).filter(e=>e!=="constructor")}function y(u){const e=i.times(u.length,g=>`${g}`),o=new Set(e);n.isBuffer(u)&&(o.add("offset"),o.add("parent")),s.isTypedArray(u)&&(o.add("buffer"),o.add("byteLength"),o.add("byteOffset"));const l=f(u).filter(g=>!o.has(g));return Array.isArray(u)?[...e,...l]:[...e.filter(g=>Object.hasOwn(u,g)),...l]}return Gr.keysIn=a,Gr}var Xr={},It;function ii(){if(It)return Xr;It=1;const n=Dt();function r(t){const s=[];for(;t;)s.push(...n.getSymbols(t)),t=Object.getPrototypeOf(t);return s}return Xr.getSymbolsIn=r,Xr}var $t;function si(){if($t)return Ur;$t=1;const n=kt(),r=_(),t=Et(),s=Qn(),i=Yn(),a=ni(),f=ii();function c(o,...l){if(o==null)return{};l=s.flatten(l);const g=y(o,l);for(let h=0;h<l.length;h++){let m=l[h];switch(typeof m){case"object":Array.isArray(m)||(m=Array.from(m));for(let q=0;q<m.length;q++){const d=m[q];i.unset(g,d)}break;case"string":case"symbol":case"number":i.unset(g,m);break}}return g}function y(o,l){return l.some(g=>Array.isArray(g)||r.isDeepKey(g))?e(o):u(o)}function u(o){const l={},g=[...a.keysIn(o),...f.getSymbolsIn(o)];for(let h=0;h<g.length;h++){const m=g[h];l[m]=o[m]}return l}function e(o){const l={},g=[...a.keysIn(o),...f.getSymbolsIn(o)];for(let h=0;h<g.length;h++){const m=g[h];l[m]=t.cloneDeepWith(o[m],q=>{if(!n.isPlainObject(q))return q})}return l}return Ur.omit=c,Ur}var Jr,Bt;function ui(){return Bt||(Bt=1,Jr=si().omit),Jr}var ai=ui();const Bi=A(ai);var Qr={},Ot;function oi(){if(Ot)return Qr;Ot=1;const n=D();function r(t,s){if(!t||!t.length)return 0;s!=null&&(s=n.iteratee(s));let i;for(let a=0;a<t.length;a++){const f=s?s(t[a]):t[a];f!==void 0&&(i===void 0?i=f:i+=f)}return i}return Qr.sumBy=r,Qr}var Yr,_t;function fi(){return _t||(_t=1,Yr=oi().sumBy),Yr}var ci=fi();const Oi=A(ci);export{Ai as a,Oi as b,gi as c,Xt as d,Qt as e,li as f,qi as g,Ii as i,$i as l,bi as m,Bi as o,pi as r,mi as s,di as t,hi as u};
|
package/dist/index.html
CHANGED
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
</script>
|
|
18
|
-
<script type="module" crossorigin src="/assets/index-
|
|
19
|
-
<link rel="stylesheet" crossorigin href="/assets/
|
|
20
|
-
<link rel="stylesheet" crossorigin href="/assets/index-CaJDJGky.css">
|
|
18
|
+
<script type="module" crossorigin src="/assets/index-BxA9vp--.js"></script>
|
|
19
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CATki2cp.css">
|
|
21
20
|
</head>
|
|
22
21
|
<body>
|
|
23
22
|
<div id="root"></div>
|
package/dist/server.cjs
CHANGED
|
@@ -973,8 +973,8 @@ function wrapCommandBus(commandBus, tracker, pluginId, manifestId) {
|
|
|
973
973
|
throw e;
|
|
974
974
|
}
|
|
975
975
|
}),
|
|
976
|
-
setInterceptor: createSafeFunction((
|
|
977
|
-
|
|
976
|
+
setInterceptor: createSafeFunction((_interceptor) => {
|
|
977
|
+
throw new Error("[Security] setInterceptor cannot be configured from PluginContext");
|
|
978
978
|
}),
|
|
979
979
|
unregisterHandler: createSafeFunction((commandType) => {
|
|
980
980
|
return commandBus.unregisterHandler(resolveType(commandType));
|
|
@@ -2506,8 +2506,8 @@ parentPort.on('message', async function(msg) {
|
|
|
2506
2506
|
createCommand: function(type, payload, actorId, metadata) {
|
|
2507
2507
|
return rawCommandBus.createCommand(type, payload, actorId, metadata);
|
|
2508
2508
|
},
|
|
2509
|
-
setInterceptor: function(
|
|
2510
|
-
|
|
2509
|
+
setInterceptor: function(_interceptor) {
|
|
2510
|
+
throw new Error('[Security] setInterceptor cannot be configured from Worker PluginContext');
|
|
2511
2511
|
}
|
|
2512
2512
|
} : undefined;
|
|
2513
2513
|
|
|
@@ -8057,7 +8057,7 @@ var PluginRuntimeComposition = class {
|
|
|
8057
8057
|
this.workerManager = workerManager;
|
|
8058
8058
|
this.id = "srv_plugin_runtime_composition";
|
|
8059
8059
|
this.name = "PluginRuntimeComposition";
|
|
8060
|
-
this.version = "2.
|
|
8060
|
+
this.version = "0.2.3";
|
|
8061
8061
|
this._isStarted = false;
|
|
8062
8062
|
}
|
|
8063
8063
|
get isStarted() {
|
|
@@ -8111,7 +8111,7 @@ var PluginLifecycleManager = class {
|
|
|
8111
8111
|
this.pluginHost = pluginHost;
|
|
8112
8112
|
this.id = "srv_plugin_lifecycle_manager";
|
|
8113
8113
|
this.name = "PluginLifecycleManager";
|
|
8114
|
-
this.version = "2.
|
|
8114
|
+
this.version = "0.2.3";
|
|
8115
8115
|
}
|
|
8116
8116
|
getPluginState(pluginId) {
|
|
8117
8117
|
return this.pluginHost.getPluginState(pluginId);
|
|
@@ -8158,7 +8158,7 @@ var PluginCapabilityGateway = class {
|
|
|
8158
8158
|
this.capabilityRegistry = capabilityRegistry;
|
|
8159
8159
|
this.id = "srv_plugin_capability_gateway";
|
|
8160
8160
|
this.name = "PluginCapabilityGateway";
|
|
8161
|
-
this.version = "2.
|
|
8161
|
+
this.version = "0.2.3";
|
|
8162
8162
|
}
|
|
8163
8163
|
listCapabilities() {
|
|
8164
8164
|
const rawCaps = this.capabilityRegistry.listCapabilities();
|
|
@@ -8212,7 +8212,7 @@ var UnifiedExtensionRegistry = class {
|
|
|
8212
8212
|
constructor() {
|
|
8213
8213
|
this.id = "srv_unified_extension_registry";
|
|
8214
8214
|
this.name = "UnifiedExtensionRegistry";
|
|
8215
|
-
this.version = "2.
|
|
8215
|
+
this.version = "0.2.3";
|
|
8216
8216
|
this._extensions = /* @__PURE__ */ new Map();
|
|
8217
8217
|
}
|
|
8218
8218
|
registerExtension(category, id, impl, meta) {
|
|
@@ -8317,7 +8317,7 @@ var PluginDistributionManager = class {
|
|
|
8317
8317
|
this.pluginHost = pluginHost;
|
|
8318
8318
|
this.id = "srv_plugin_distribution_manager";
|
|
8319
8319
|
this.name = "PluginDistributionManager";
|
|
8320
|
-
this.version = "2.
|
|
8320
|
+
this.version = "0.2.3";
|
|
8321
8321
|
this._repositories = /* @__PURE__ */ new Map();
|
|
8322
8322
|
}
|
|
8323
8323
|
registerRepository(repo) {
|
|
@@ -8406,7 +8406,7 @@ function validatePluginStateTransition(currentState, nextState, pluginId) {
|
|
|
8406
8406
|
}
|
|
8407
8407
|
var ACTIVATION_TIMEOUT_MS = 5e3;
|
|
8408
8408
|
var DEACTIVATION_TIMEOUT_MS = 5e3;
|
|
8409
|
-
var OPENLEARN_VERSION = "2.
|
|
8409
|
+
var OPENLEARN_VERSION = "0.2.3";
|
|
8410
8410
|
var PluginHost = class {
|
|
8411
8411
|
constructor(serviceRegistry, esmLoader, db2, pluginsDir) {
|
|
8412
8412
|
this.serviceRegistry = serviceRegistry;
|
|
@@ -16020,7 +16020,7 @@ var StartupTimeoutError = class extends PlatformBootstrapError {
|
|
|
16020
16020
|
this.name = "StartupTimeoutError";
|
|
16021
16021
|
}
|
|
16022
16022
|
};
|
|
16023
|
-
var PLATFORM_VERSION = "2.
|
|
16023
|
+
var PLATFORM_VERSION = "0.2.3";
|
|
16024
16024
|
var BOOTSTRAP_STAGE_NAMES = Object.freeze([
|
|
16025
16025
|
"Created" /* Created */,
|
|
16026
16026
|
"Configuring" /* Configuring */,
|
|
@@ -18383,6 +18383,26 @@ function getActorId(req) {
|
|
|
18383
18383
|
return "user-frontend";
|
|
18384
18384
|
}
|
|
18385
18385
|
}
|
|
18386
|
+
function requireAuth(...roles) {
|
|
18387
|
+
return (req, res, next) => {
|
|
18388
|
+
const token = getCookieToken(req);
|
|
18389
|
+
if (!token) return res.status(401).json({ success: false, error: "Authentication required" });
|
|
18390
|
+
const session = getValidSession(token);
|
|
18391
|
+
if (!session) return res.status(401).json({ success: false, error: "Session expired or invalid" });
|
|
18392
|
+
if (roles.length > 0) {
|
|
18393
|
+
let userRole = session.role;
|
|
18394
|
+
if (session.username === "admin" || session.userId === "usr_admin" || userRole === "admin") {
|
|
18395
|
+
userRole = "administrator";
|
|
18396
|
+
}
|
|
18397
|
+
const effectiveRoles = roles.map((r) => r === "admin" ? "administrator" : r);
|
|
18398
|
+
if (!effectiveRoles.includes(userRole)) {
|
|
18399
|
+
return res.status(403).json({ success: false, error: `Role ${session.role} not allowed. Required: ${roles.join(", ")}` });
|
|
18400
|
+
}
|
|
18401
|
+
}
|
|
18402
|
+
req.session = session;
|
|
18403
|
+
next();
|
|
18404
|
+
};
|
|
18405
|
+
}
|
|
18386
18406
|
function checkIsTeacherOrAdmin(req) {
|
|
18387
18407
|
const token = getCookieToken(req);
|
|
18388
18408
|
if (!token) return false;
|
|
@@ -20079,7 +20099,8 @@ function registerBridgeRoutes(ctx) {
|
|
|
20079
20099
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
20080
20100
|
res.send(BRIDGE_SDK_CODE);
|
|
20081
20101
|
});
|
|
20082
|
-
app.get("/runtime/:uuid", (req, res) => {
|
|
20102
|
+
app.get("/runtime/:uuid", (req, res, next) => {
|
|
20103
|
+
if (req.path.endsWith("/")) return next();
|
|
20083
20104
|
res.redirect(`/runtime/${req.params.uuid}/`);
|
|
20084
20105
|
});
|
|
20085
20106
|
app.get("/runtime/:uuid/*", (req, res) => {
|
|
@@ -20139,6 +20160,7 @@ function registerBridgeRoutes(ctx) {
|
|
|
20139
20160
|
|
|
20140
20161
|
// server/routes/lessons.ts
|
|
20141
20162
|
var import_genai3 = require("@google/genai");
|
|
20163
|
+
var import_uuid16 = require("uuid");
|
|
20142
20164
|
function registerLessonsRoutes(ctx) {
|
|
20143
20165
|
const {
|
|
20144
20166
|
app,
|
|
@@ -20548,6 +20570,72 @@ Provide a short, friendly, and helpful hint (1-2 sentences) directly related to
|
|
|
20548
20570
|
res.status(500).json({ error: e.message });
|
|
20549
20571
|
}
|
|
20550
20572
|
});
|
|
20573
|
+
app.delete("/api/lessons/:id", async (req, res) => {
|
|
20574
|
+
try {
|
|
20575
|
+
const { id } = req.params;
|
|
20576
|
+
kernelContainer.db.prepare("DELETE FROM whiteboard_elements WHERE lesson_id = ?").run(id);
|
|
20577
|
+
kernelContainer.db.prepare("DELETE FROM student_lesson_progress WHERE lesson_id = ?").run(id);
|
|
20578
|
+
kernelContainer.db.prepare("DELETE FROM schedules WHERE lesson_id = ?").run(id);
|
|
20579
|
+
kernelContainer.db.prepare("DELETE FROM assignments WHERE lesson_id = ?").run(id);
|
|
20580
|
+
const result = kernelContainer.db.prepare("DELETE FROM lessons WHERE id = ?").run(id);
|
|
20581
|
+
if (result.changes === 0) {
|
|
20582
|
+
return res.status(404).json({ error: "Lesson not found" });
|
|
20583
|
+
}
|
|
20584
|
+
res.json({ success: true });
|
|
20585
|
+
} catch (e) {
|
|
20586
|
+
res.status(500).json({ error: e.message });
|
|
20587
|
+
}
|
|
20588
|
+
});
|
|
20589
|
+
app.get("/api/lessons/:id/stats", (req, res) => {
|
|
20590
|
+
try {
|
|
20591
|
+
const { id } = req.params;
|
|
20592
|
+
const whiteboardCount = kernelContainer.db.prepare(
|
|
20593
|
+
"SELECT COUNT(*) as count FROM whiteboard_elements WHERE lesson_id = ?"
|
|
20594
|
+
).get(id).count;
|
|
20595
|
+
const scheduleCount = kernelContainer.db.prepare(
|
|
20596
|
+
"SELECT COUNT(*) as count FROM schedules WHERE lesson_id = ?"
|
|
20597
|
+
).get(id).count;
|
|
20598
|
+
const enrollmentCount = kernelContainer.db.prepare(
|
|
20599
|
+
"SELECT COUNT(*) as count FROM student_lesson_progress WHERE lesson_id = ?"
|
|
20600
|
+
).get(id).count;
|
|
20601
|
+
const assignmentCount = kernelContainer.db.prepare(
|
|
20602
|
+
"SELECT COUNT(*) as count FROM assignments WHERE lesson_id = ?"
|
|
20603
|
+
).get(id).count;
|
|
20604
|
+
res.json({ whiteboardCount, scheduleCount, enrollmentCount, assignmentCount });
|
|
20605
|
+
} catch (e) {
|
|
20606
|
+
res.status(500).json({ error: e.message });
|
|
20607
|
+
}
|
|
20608
|
+
});
|
|
20609
|
+
app.post("/api/lessons/:id/clone", async (req, res) => {
|
|
20610
|
+
try {
|
|
20611
|
+
const { id } = req.params;
|
|
20612
|
+
const original = kernelContainer.db.prepare("SELECT * FROM lessons WHERE id = ?").get(id);
|
|
20613
|
+
if (!original) {
|
|
20614
|
+
return res.status(404).json({ error: "Lesson not found" });
|
|
20615
|
+
}
|
|
20616
|
+
const newId = (0, import_uuid16.v7)();
|
|
20617
|
+
const now = Date.now();
|
|
20618
|
+
const newTitle = `\u526F\u672C-${original.title}`;
|
|
20619
|
+
kernelContainer.db.prepare(
|
|
20620
|
+
"INSERT INTO lessons (id, title, content, timeline, progress_mode, progress_conditions, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
|
20621
|
+
).run(newId, newTitle, original.content, original.timeline, original.progress_mode, original.progress_conditions, now, now);
|
|
20622
|
+
const whiteboardElements = kernelContainer.db.prepare(
|
|
20623
|
+
"SELECT * FROM whiteboard_elements WHERE lesson_id = ?"
|
|
20624
|
+
).all(id);
|
|
20625
|
+
const insertElement = kernelContainer.db.prepare(
|
|
20626
|
+
"INSERT INTO whiteboard_elements (id, lesson_id, type, data, created_at) VALUES (?, ?, ?, ?, ?)"
|
|
20627
|
+
);
|
|
20628
|
+
for (const el of whiteboardElements) {
|
|
20629
|
+
insertElement.run((0, import_uuid16.v7)(), newId, el.type, el.data, now);
|
|
20630
|
+
}
|
|
20631
|
+
const cloned = kernelContainer.db.prepare(
|
|
20632
|
+
"SELECT l.*, 0 as enrollment_count FROM lessons l WHERE l.id = ?"
|
|
20633
|
+
).get(newId);
|
|
20634
|
+
res.json({ success: true, lesson: cloned });
|
|
20635
|
+
} catch (e) {
|
|
20636
|
+
res.status(500).json({ error: e.message });
|
|
20637
|
+
}
|
|
20638
|
+
});
|
|
20551
20639
|
}
|
|
20552
20640
|
|
|
20553
20641
|
// server/routes/workspace.ts
|
|
@@ -20792,7 +20880,7 @@ function registerAdminRoutes(ctx) {
|
|
|
20792
20880
|
runGeminiAgentChat: runGeminiAgentChat2,
|
|
20793
20881
|
runOpenAIAgentChat: runOpenAIAgentChat2
|
|
20794
20882
|
} = ctx;
|
|
20795
|
-
app.post("/api/admin/seed-demo", (req, res) => {
|
|
20883
|
+
app.post("/api/admin/seed-demo", requireAuth("administrator"), (req, res) => {
|
|
20796
20884
|
try {
|
|
20797
20885
|
const db2 = kernelContainer.db;
|
|
20798
20886
|
const DEMO_CLASS_ID = "demo-class";
|
|
@@ -20808,7 +20896,7 @@ function registerAdminRoutes(ctx) {
|
|
|
20808
20896
|
db2.prepare("INSERT INTO classes (id, name, description, created_at) VALUES (?, ?, ?, ?)").run(
|
|
20809
20897
|
DEMO_CLASS_ID,
|
|
20810
20898
|
"\u4EBA\u5DE5\u667A\u80FD\u4E0E\u521B\u610F\u7F16\u7A0B\u793A\u8303\u73ED",
|
|
20811
|
-
"\u8FD9\u662F\u7CFB\u7EDF\u521D\u59CB\u5316\u7684\u793A\u4F8B\u8BFE\u7A0B\u73ED\u7EA7\uFF0C\u7528\u4E8E\u6559\u5B66\u4F53\u9A8C
|
|
20899
|
+
"\u8FD9\u662F\u7CFB\u7EDF\u521D\u59CB\u5316\u7684\u793A\u4F8B\u8BFE\u7A0B\u73ED\u7EA7\uFF0C\u7528\u4E8E\u6559\u5B66\u4F53\u9A8C?",
|
|
20812
20900
|
Date.now()
|
|
20813
20901
|
);
|
|
20814
20902
|
}
|
|
@@ -20836,7 +20924,7 @@ function registerAdminRoutes(ctx) {
|
|
|
20836
20924
|
lessonId = "demo-lesson";
|
|
20837
20925
|
db2.prepare("INSERT INTO lessons (id, title, content, created_at, updated_at) VALUES (?, ?, ?, ?, ?)").run(
|
|
20838
20926
|
lessonId,
|
|
20839
|
-
"\u521D\u8BC6 Python\uFF1A\u667A\u80FD\u767D\u677F\u521B\u610F\u7F16
|
|
20927
|
+
"\u521D\u8BC6 Python\uFF1A\u667A\u80FD\u767D\u677F\u521B\u610F\u7F16?",
|
|
20840
20928
|
JSON.stringify({ elements: [] }),
|
|
20841
20929
|
Date.now(),
|
|
20842
20930
|
Date.now()
|
|
@@ -20858,7 +20946,7 @@ function registerAdminRoutes(ctx) {
|
|
|
20858
20946
|
res.status(500).json({ error: e.message });
|
|
20859
20947
|
}
|
|
20860
20948
|
});
|
|
20861
|
-
app.post("/api/classes/import", (req, res) => {
|
|
20949
|
+
app.post("/api/classes/import", requireAuth("teacher", "administrator"), (req, res) => {
|
|
20862
20950
|
try {
|
|
20863
20951
|
const { classes } = req.body;
|
|
20864
20952
|
if (!classes || !Array.isArray(classes)) {
|
|
@@ -20908,7 +20996,7 @@ function registerAdminRoutes(ctx) {
|
|
|
20908
20996
|
res.status(500).json({ error: e.message });
|
|
20909
20997
|
}
|
|
20910
20998
|
});
|
|
20911
|
-
app.post("/api/students/import", (req, res) => {
|
|
20999
|
+
app.post("/api/students/import", requireAuth("teacher", "administrator"), (req, res) => {
|
|
20912
21000
|
try {
|
|
20913
21001
|
const { students } = req.body;
|
|
20914
21002
|
if (!students || !Array.isArray(students)) {
|
|
@@ -21507,16 +21595,16 @@ function registerRosterRoutes(ctx) {
|
|
|
21507
21595
|
res.status(550).json({ error: e.message });
|
|
21508
21596
|
}
|
|
21509
21597
|
});
|
|
21510
|
-
app.get("/api/users", async (req, res) => {
|
|
21598
|
+
app.get("/api/users", requireAuth("administrator"), async (req, res) => {
|
|
21511
21599
|
try {
|
|
21512
|
-
const cmd = kernelContainer.commandBus.createCommand("user.list", {},
|
|
21600
|
+
const cmd = kernelContainer.commandBus.createCommand("user.list", {}, getActorId(req));
|
|
21513
21601
|
const users = await kernelContainer.commandBus.execute(cmd);
|
|
21514
21602
|
res.json(users);
|
|
21515
21603
|
} catch (e) {
|
|
21516
21604
|
res.status(550).json({ error: e.message });
|
|
21517
21605
|
}
|
|
21518
21606
|
});
|
|
21519
|
-
app.post("/api/users", async (req, res) => {
|
|
21607
|
+
app.post("/api/users", requireAuth("administrator"), async (req, res) => {
|
|
21520
21608
|
try {
|
|
21521
21609
|
const { username, password, role, name, status = "active" } = req.body;
|
|
21522
21610
|
const cmd = kernelContainer.commandBus.createCommand("user.create", {
|
|
@@ -21525,14 +21613,14 @@ function registerRosterRoutes(ctx) {
|
|
|
21525
21613
|
role,
|
|
21526
21614
|
name,
|
|
21527
21615
|
status
|
|
21528
|
-
},
|
|
21616
|
+
}, getActorId(req));
|
|
21529
21617
|
const result = await kernelContainer.commandBus.execute(cmd);
|
|
21530
21618
|
res.json(result);
|
|
21531
21619
|
} catch (e) {
|
|
21532
21620
|
res.status(550).json({ error: e.message });
|
|
21533
21621
|
}
|
|
21534
21622
|
});
|
|
21535
|
-
app.put("/api/users/:id", async (req, res) => {
|
|
21623
|
+
app.put("/api/users/:id", requireAuth("administrator"), async (req, res) => {
|
|
21536
21624
|
try {
|
|
21537
21625
|
const { username, role, name, password, status } = req.body;
|
|
21538
21626
|
const cmd = kernelContainer.commandBus.createCommand("user.update", {
|
|
@@ -21542,18 +21630,18 @@ function registerRosterRoutes(ctx) {
|
|
|
21542
21630
|
name,
|
|
21543
21631
|
password,
|
|
21544
21632
|
status
|
|
21545
|
-
},
|
|
21633
|
+
}, getActorId(req));
|
|
21546
21634
|
const result = await kernelContainer.commandBus.execute(cmd);
|
|
21547
21635
|
res.json(result);
|
|
21548
21636
|
} catch (e) {
|
|
21549
21637
|
res.status(550).json({ error: e.message });
|
|
21550
21638
|
}
|
|
21551
21639
|
});
|
|
21552
|
-
app.delete("/api/users/:id", async (req, res) => {
|
|
21640
|
+
app.delete("/api/users/:id", requireAuth("administrator"), async (req, res) => {
|
|
21553
21641
|
try {
|
|
21554
21642
|
const cmd = kernelContainer.commandBus.createCommand("user.delete", {
|
|
21555
21643
|
userId: req.params.id
|
|
21556
|
-
},
|
|
21644
|
+
}, getActorId(req));
|
|
21557
21645
|
const result = await kernelContainer.commandBus.execute(cmd);
|
|
21558
21646
|
res.json(result);
|
|
21559
21647
|
} catch (e) {
|
|
@@ -21568,7 +21656,7 @@ function registerRosterRoutes(ctx) {
|
|
|
21568
21656
|
res.status(500).json({ error: e.message });
|
|
21569
21657
|
}
|
|
21570
21658
|
});
|
|
21571
|
-
app.post("/api/labs", (req, res) => {
|
|
21659
|
+
app.post("/api/labs", requireAuth("teacher", "administrator"), (req, res) => {
|
|
21572
21660
|
try {
|
|
21573
21661
|
const { room_number, rows, cols } = req.body;
|
|
21574
21662
|
const id = "lab_" + Math.random().toString(36).slice(2, 10);
|
|
@@ -21580,7 +21668,7 @@ function registerRosterRoutes(ctx) {
|
|
|
21580
21668
|
res.status(500).json({ error: e.message });
|
|
21581
21669
|
}
|
|
21582
21670
|
});
|
|
21583
|
-
app.put("/api/labs/:id", (req, res) => {
|
|
21671
|
+
app.put("/api/labs/:id", requireAuth("teacher", "administrator"), (req, res) => {
|
|
21584
21672
|
try {
|
|
21585
21673
|
const { room_number, rows, cols } = req.body;
|
|
21586
21674
|
kernelContainer.db.prepare(
|
|
@@ -21591,7 +21679,7 @@ function registerRosterRoutes(ctx) {
|
|
|
21591
21679
|
res.status(500).json({ error: e.message });
|
|
21592
21680
|
}
|
|
21593
21681
|
});
|
|
21594
|
-
app.delete("/api/labs/:id", (req, res) => {
|
|
21682
|
+
app.delete("/api/labs/:id", requireAuth("teacher", "administrator"), (req, res) => {
|
|
21595
21683
|
try {
|
|
21596
21684
|
kernelContainer.db.prepare("DELETE FROM computer_labs WHERE id = ?").run(req.params.id);
|
|
21597
21685
|
kernelContainer.db.prepare("DELETE FROM student_seats WHERE lab_id = ?").run(req.params.id);
|
|
@@ -21610,7 +21698,7 @@ function registerRosterRoutes(ctx) {
|
|
|
21610
21698
|
res.status(500).json({ error: e.message });
|
|
21611
21699
|
}
|
|
21612
21700
|
});
|
|
21613
|
-
app.post("/api/classes/:classId/seats", (req, res) => {
|
|
21701
|
+
app.post("/api/classes/:classId/seats", requireAuth("teacher", "administrator"), (req, res) => {
|
|
21614
21702
|
try {
|
|
21615
21703
|
const { lab_id, seats } = req.body;
|
|
21616
21704
|
kernelContainer.db.prepare("UPDATE classes SET lab_id = ? WHERE id = ?").run(lab_id || null, req.params.classId);
|
|
@@ -21808,7 +21896,7 @@ function registerRosterRoutes(ctx) {
|
|
|
21808
21896
|
res.status(500).json({ error: e.message });
|
|
21809
21897
|
}
|
|
21810
21898
|
});
|
|
21811
|
-
app.post("/api/classes/:id/students/bulk-enroll", (req, res) => {
|
|
21899
|
+
app.post("/api/classes/:id/students/bulk-enroll", requireAuth("teacher", "administrator"), (req, res) => {
|
|
21812
21900
|
try {
|
|
21813
21901
|
const { students } = req.body;
|
|
21814
21902
|
const classId = req.params.id;
|
|
@@ -22256,9 +22344,9 @@ Provide a grade score (0-100) and brief feedback. Ensure you output in this exac
|
|
|
22256
22344
|
} catch (e) {
|
|
22257
22345
|
}
|
|
22258
22346
|
}
|
|
22259
|
-
const { v7:
|
|
22347
|
+
const { v7: uuidv717 } = await import("uuid");
|
|
22260
22348
|
await kernelContainer.commandBus.execute({
|
|
22261
|
-
id:
|
|
22349
|
+
id: uuidv717(),
|
|
22262
22350
|
type: "ai.apply_grade",
|
|
22263
22351
|
actorId: "system",
|
|
22264
22352
|
timestamp: Date.now(),
|
|
@@ -23353,6 +23441,28 @@ async function checkVersion(source, installedVersion) {
|
|
|
23353
23441
|
}
|
|
23354
23442
|
|
|
23355
23443
|
// server/routes/plugins.ts
|
|
23444
|
+
function isSafeExternalUrl(urlStr) {
|
|
23445
|
+
try {
|
|
23446
|
+
const parsed = new URL(urlStr);
|
|
23447
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
23448
|
+
return { safe: false, reason: "Only HTTP and HTTPS protocols are allowed" };
|
|
23449
|
+
}
|
|
23450
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
23451
|
+
if (hostname === "localhost" || hostname.endsWith(".localhost") || hostname.endsWith(".local") || hostname === "0.0.0.0" || hostname === "::1" || hostname === "[::1]") {
|
|
23452
|
+
return { safe: false, reason: "Access to loopback/local addresses is forbidden" };
|
|
23453
|
+
}
|
|
23454
|
+
const ipv4Match = hostname.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
23455
|
+
if (ipv4Match) {
|
|
23456
|
+
const octets = ipv4Match.slice(1).map(Number);
|
|
23457
|
+
if (octets[0] === 127 || octets[0] === 10 || octets[0] === 172 && octets[1] >= 16 && octets[1] <= 31 || octets[0] === 192 && octets[1] === 168 || octets[0] === 169 && octets[1] === 254 || octets[0] === 0 || octets[0] >= 224) {
|
|
23458
|
+
return { safe: false, reason: "Access to private or link-local IP addresses is forbidden" };
|
|
23459
|
+
}
|
|
23460
|
+
}
|
|
23461
|
+
return { safe: true };
|
|
23462
|
+
} catch (e) {
|
|
23463
|
+
return { safe: false, reason: `Invalid URL format: ${e.message}` };
|
|
23464
|
+
}
|
|
23465
|
+
}
|
|
23356
23466
|
function registerPluginsRoutes(ctx) {
|
|
23357
23467
|
const {
|
|
23358
23468
|
app,
|
|
@@ -23500,12 +23610,19 @@ function registerPluginsRoutes(ctx) {
|
|
|
23500
23610
|
res.status(500).json({ success: false, error: e.message });
|
|
23501
23611
|
}
|
|
23502
23612
|
});
|
|
23503
|
-
app.post("/api/plugins/:id(*)/one-click-update", async (req, res) => {
|
|
23613
|
+
app.post("/api/plugins/:id(*)/one-click-update", requireAuth("administrator"), async (req, res) => {
|
|
23504
23614
|
try {
|
|
23505
23615
|
const targetPluginId = decodeURIComponent(req.params.id);
|
|
23506
23616
|
const { downloadUrl } = req.body || {};
|
|
23507
23617
|
let zipBuffer;
|
|
23508
23618
|
if (downloadUrl) {
|
|
23619
|
+
const urlCheck = isSafeExternalUrl(downloadUrl);
|
|
23620
|
+
if (!urlCheck.safe) {
|
|
23621
|
+
return res.status(400).json({
|
|
23622
|
+
success: false,
|
|
23623
|
+
error: `\u5B89\u5168\u62E6\u622A: \u975E\u6CD5\u4E0B\u8F7D\u5730\u5740 (${urlCheck.reason})`
|
|
23624
|
+
});
|
|
23625
|
+
}
|
|
23509
23626
|
try {
|
|
23510
23627
|
const resp = await fetch(downloadUrl, {
|
|
23511
23628
|
headers: { "User-Agent": "OpenLearnV2-PluginUpdater/1.0" },
|
|
@@ -23583,7 +23700,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23583
23700
|
res.status(500).json({ success: false, error: e.message });
|
|
23584
23701
|
}
|
|
23585
23702
|
});
|
|
23586
|
-
app.post("/api/plugins/:id(*)/config", (req, res) => {
|
|
23703
|
+
app.post("/api/plugins/:id(*)/config", requireAuth("administrator"), (req, res) => {
|
|
23587
23704
|
try {
|
|
23588
23705
|
const rawId = decodeURIComponent(req.params.id);
|
|
23589
23706
|
const pluginId = kernelContainer.pluginHost.resolvePluginUuid(rawId);
|
|
@@ -23602,7 +23719,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23602
23719
|
res.status(500).json({ success: false, error: e.message });
|
|
23603
23720
|
}
|
|
23604
23721
|
});
|
|
23605
|
-
app.post("/api/plugins/:id(*)/toggle", async (req, res) => {
|
|
23722
|
+
app.post("/api/plugins/:id(*)/toggle", requireAuth("administrator"), async (req, res) => {
|
|
23606
23723
|
try {
|
|
23607
23724
|
const rawId = decodeURIComponent(req.params.id);
|
|
23608
23725
|
const cmd = kernelContainer.commandBus.createCommand(
|
|
@@ -23616,7 +23733,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23616
23733
|
res.status(500).json({ success: false, error: err.message });
|
|
23617
23734
|
}
|
|
23618
23735
|
});
|
|
23619
|
-
app.delete("/api/plugins/:id(*)", async (req, res) => {
|
|
23736
|
+
app.delete("/api/plugins/:id(*)", requireAuth("administrator"), async (req, res) => {
|
|
23620
23737
|
try {
|
|
23621
23738
|
const rawId = decodeURIComponent(req.params.id);
|
|
23622
23739
|
const cmd = kernelContainer.commandBus.createCommand(
|
|
@@ -23644,7 +23761,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23644
23761
|
res.status(404).json({ success: false, error: err.message });
|
|
23645
23762
|
}
|
|
23646
23763
|
});
|
|
23647
|
-
app.post("/api/plugins", async (req, res) => {
|
|
23764
|
+
app.post("/api/plugins", requireAuth("administrator"), async (req, res) => {
|
|
23648
23765
|
try {
|
|
23649
23766
|
const { sourceCode } = req.body;
|
|
23650
23767
|
const cmd = kernelContainer.commandBus.createCommand(
|
|
@@ -23659,7 +23776,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23659
23776
|
res.status(500).json({ success: false, error: err.message });
|
|
23660
23777
|
}
|
|
23661
23778
|
});
|
|
23662
|
-
app.post("/api/plugins/upload-zip", async (req, res) => {
|
|
23779
|
+
app.post("/api/plugins/upload-zip", requireAuth("administrator"), async (req, res) => {
|
|
23663
23780
|
try {
|
|
23664
23781
|
const { base64Data, filename, executionMode } = req.body;
|
|
23665
23782
|
const cmd = kernelContainer.commandBus.createCommand(
|
|
@@ -23674,7 +23791,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23674
23791
|
res.status(500).json({ success: false, error: err.message });
|
|
23675
23792
|
}
|
|
23676
23793
|
});
|
|
23677
|
-
app.post("/api/plugins/upload-zip-raw", import_express2.default.raw({ type: "application/octet-stream", limit: "400mb" }), async (req, res) => {
|
|
23794
|
+
app.post("/api/plugins/upload-zip-raw", requireAuth("administrator"), import_express2.default.raw({ type: "application/octet-stream", limit: "400mb" }), async (req, res) => {
|
|
23678
23795
|
try {
|
|
23679
23796
|
const zipBuffer = req.body;
|
|
23680
23797
|
const filename = req.headers["x-filename"] ? decodeURIComponent(req.headers["x-filename"]) : "plugin.zip";
|
|
@@ -23718,6 +23835,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23718
23835
|
});
|
|
23719
23836
|
app.post(
|
|
23720
23837
|
"/api/plugins/:id(*)/update-zip-raw",
|
|
23838
|
+
requireAuth("administrator"),
|
|
23721
23839
|
import_express2.default.raw({ type: "application/octet-stream", limit: "400mb" }),
|
|
23722
23840
|
async (req, res) => {
|
|
23723
23841
|
try {
|
|
@@ -23804,7 +23922,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23804
23922
|
res.status(500).json({ error: e.message });
|
|
23805
23923
|
}
|
|
23806
23924
|
});
|
|
23807
|
-
app.post("/api/ai-providers", (req, res) => {
|
|
23925
|
+
app.post("/api/ai-providers", requireAuth("administrator"), (req, res) => {
|
|
23808
23926
|
try {
|
|
23809
23927
|
const { name, api_url, api_key, model_name } = req.body;
|
|
23810
23928
|
if (!name || !api_url || !model_name) {
|
|
@@ -23819,7 +23937,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23819
23937
|
res.status(500).json({ error: e.message });
|
|
23820
23938
|
}
|
|
23821
23939
|
});
|
|
23822
|
-
app.put("/api/ai-providers/:id", (req, res) => {
|
|
23940
|
+
app.put("/api/ai-providers/:id", requireAuth("administrator"), (req, res) => {
|
|
23823
23941
|
try {
|
|
23824
23942
|
const { name, api_url, api_key, model_name } = req.body;
|
|
23825
23943
|
if (!name || !api_url || !model_name) {
|
|
@@ -23839,7 +23957,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23839
23957
|
res.status(500).json({ error: e.message });
|
|
23840
23958
|
}
|
|
23841
23959
|
});
|
|
23842
|
-
app.delete("/api/ai-providers/:id", (req, res) => {
|
|
23960
|
+
app.delete("/api/ai-providers/:id", requireAuth("administrator"), (req, res) => {
|
|
23843
23961
|
try {
|
|
23844
23962
|
kernelContainer.db.prepare("DELETE FROM ai_providers WHERE id = ?").run(req.params.id);
|
|
23845
23963
|
res.json({ success: true });
|
|
@@ -23859,7 +23977,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23859
23977
|
res.status(500).json({ error: e.message });
|
|
23860
23978
|
}
|
|
23861
23979
|
});
|
|
23862
|
-
app.put("/api/site-settings", (req, res) => {
|
|
23980
|
+
app.put("/api/site-settings", requireAuth("administrator"), (req, res) => {
|
|
23863
23981
|
try {
|
|
23864
23982
|
const { siteName, slogan, logoUrl } = req.body || {};
|
|
23865
23983
|
kernelContainer.db.prepare(
|
|
@@ -23874,7 +23992,7 @@ function registerPluginsRoutes(ctx) {
|
|
|
23874
23992
|
res.status(500).json({ error: e.message });
|
|
23875
23993
|
}
|
|
23876
23994
|
});
|
|
23877
|
-
app.post("/api/ai-providers/test", async (req, res) => {
|
|
23995
|
+
app.post("/api/ai-providers/test", requireAuth("administrator"), async (req, res) => {
|
|
23878
23996
|
try {
|
|
23879
23997
|
const { api_url, api_key: providedKey, model_name } = req.body;
|
|
23880
23998
|
if (!api_url || !model_name) {
|
|
@@ -23975,8 +24093,8 @@ async function startServer() {
|
|
|
23975
24093
|
standardHeaders: true,
|
|
23976
24094
|
legacyHeaders: false
|
|
23977
24095
|
});
|
|
23978
|
-
app.use(import_express3.default.json({ limit: "
|
|
23979
|
-
app.use(import_express3.default.urlencoded({ limit: "
|
|
24096
|
+
app.use(import_express3.default.json({ limit: "10mb" }));
|
|
24097
|
+
app.use(import_express3.default.urlencoded({ limit: "10mb", extended: true }));
|
|
23980
24098
|
app.use("/uploads", import_express3.default.static(import_path14.default.join(process.cwd(), "uploads")));
|
|
23981
24099
|
app.use("/plugins", import_express3.default.static(import_path14.default.join(process.cwd(), "plugins")));
|
|
23982
24100
|
app.use((req, res, next) => {
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as m}from"./vendor-konva-GivUq6dt.js";import{j as e,G as h,M as w,a as v,X as y}from"./whiteboard-Dp8tFXTO.js";const j=(function(){const l=typeof document<"u"&&document.createElement("link").relList;return l&&l.supports&&l.supports("modulepreload")?"modulepreload":"preload"})(),E=function(n){return"/"+n},g={},N=function(l,c,f){let i=Promise.resolve();if(c&&c.length>0){let t=function(r){return Promise.all(r.map(a=>Promise.resolve(a).then(u=>({status:"fulfilled",value:u}),u=>({status:"rejected",reason:u}))))};document.getElementsByTagName("link");const s=document.querySelector("meta[property=csp-nonce]"),x=s?.nonce||s?.getAttribute("nonce");i=t(c.map(r=>{if(r=E(r),r in g)return;g[r]=!0;const a=r.endsWith(".css"),u=a?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${r}"]${u}`))return;const o=document.createElement("link");if(o.rel=a?"stylesheet":j,a||(o.as="script"),o.crossOrigin="",o.href=r,x&&o.setAttribute("nonce",x),document.head.appendChild(o),a)return new Promise((p,b)=>{o.addEventListener("load",p),o.addEventListener("error",()=>b(new Error(`Unable to preload CSS for ${r}`)))})}))}function d(t){const s=new Event("vite:preloadError",{cancelable:!0});if(s.payload=t,window.dispatchEvent(s),!s.defaultPrevented)throw t}return i.then(t=>{for(const s of t||[])s.status==="rejected"&&d(s.reason);return l().catch(d)})},_=m.lazy(()=>N(()=>Promise.resolve().then(()=>F),void 0).then(n=>({default:n.InteractiveCoursewareViewer}))),P=Object.freeze(Object.defineProperty({__proto__:null,CoursewareViewer:_},Symbol.toStringTag,{value:"Module"}));function S({coursewareId:n,onClose:l}){const[c,f]=m.useState(!1),i=m.useRef(null);m.useEffect(()=>{const t=()=>{f(!!document.fullscreenElement&&document.fullscreenElement===i.current)};return document.addEventListener("fullscreenchange",t),()=>{document.removeEventListener("fullscreenchange",t)}},[]);const d=()=>{const t=i.current;t&&(document.fullscreenElement?document.exitFullscreen?document.exitFullscreen():document.webkitExitFullscreen&&document.webkitExitFullscreen():t.requestFullscreen?t.requestFullscreen():t.webkitRequestFullscreen&&t.webkitRequestFullscreen())};return n?e.jsxs("div",{ref:i,className:"flex flex-col h-full bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden relative",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-2 bg-gray-100 border-b border-gray-200 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2 select-none",children:[e.jsx(h,{size:16,className:"text-indigo-500"}),e.jsx("span",{className:"font-semibold text-sm text-gray-700",children:"Interactive Courseware"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:d,className:"p-1 hover:bg-gray-200 rounded-lg text-gray-500 transition-colors cursor-pointer",title:c?"退出全屏":"全屏播放",children:c?e.jsx(w,{size:16}):e.jsx(v,{size:16})}),l&&e.jsx("button",{onClick:l,className:"p-1 hover:bg-gray-200 rounded-lg text-gray-500 transition-colors cursor-pointer",children:e.jsx(y,{size:16})})]})]}),e.jsx("div",{className:"flex-1 relative bg-white",children:e.jsx("iframe",{src:`/api/courseware/${n}`,sandbox:"allow-scripts allow-same-origin allow-downloads allow-forms",allowFullScreen:!0,className:"w-full h-full border-none",title:"Interactive Courseware"})})]}):e.jsxs("div",{className:"flex flex-col items-center justify-center h-full text-gray-400 bg-gray-50 rounded-xl border border-dashed border-gray-300",children:[e.jsx(h,{size:48,className:"mb-4 text-gray-300 opacity-50"}),e.jsx("h3",{className:"text-lg font-medium text-gray-700",children:"No Courseware Selected"}),e.jsx("p",{className:"mt-2 text-sm text-center",children:"Please select a courseware from the list to view it interactively."})]})}const F=Object.freeze(Object.defineProperty({__proto__:null,InteractiveCoursewareViewer:S},Symbol.toStringTag,{value:"Module"}));export{N as _,P as i};
|