@oaknational/google-classroom-addon 1.4.0 → 1.6.0

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/README.md CHANGED
@@ -6,3 +6,23 @@
6
6
 
7
7
  This library contains UI components and API helper functions for the Google Classroom Add-on produced by
8
8
  [Oak National Academy](https://www.thenational.academy/).
9
+
10
+
11
+ ## google-auth-library and @googleapis/classroom versions
12
+ These are currently set to specific versions.
13
+ ```
14
+ "@googleapis/classroom": "4.9.0",
15
+ "google-auth-library": "9.15.1",
16
+ ```
17
+ The reason for this is that in OWA we are limited to using version 9.15.1 of google-auth-library due to our OIDC
18
+ Firestore connection that is used for the pupil Firestore. At the time of writing, using version 10 of the
19
+ google-auth-library causes the OIDC connection to break.
20
+
21
+ As we are limited to using this version of the google-auth-library it means we must also use an older version of the
22
+ Google Classroom API as the latest version that supports google-auth-library v9 is version 4.9.0.
23
+
24
+ When google-auth-library v10 is supported in OWA we can upgrade both packages to their latest versions.
25
+
26
+ There was a [PR in OWA](https://github.com/oaknational/Oak-Web-Application/pull/3819) where we made this change.
27
+
28
+ This issue has also been noted before in [this thread](https://github.com/vercel/vercel/issues/13811#issuecomment-3256606384) in the Vercel repository.
@@ -1,8 +1,8 @@
1
- "use strict";var e=require("crypto"),t=require("google-auth-library");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=r(e);function i(e,t,r,n){return new(r||(r=Promise))(function(i,o){function s(e){try{c(n.next(e))}catch(e){o(e)}}function a(e){try{c(n.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(s,a)}c((n=n.apply(e,t||[])).next())})}function o(e,t){var r,n,i,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]},s=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return s.next=a(0),s.throw=a(1),s.return=a(2),"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(c){return function(a){if(r)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(r=1,n&&(i=2&a[0]?n.return:a[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,a[1])).done)return i;switch(n=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,n=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=o.trys,(i=i.length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]<i[3])){o.label=a[1];break}if(6===a[0]&&o.label<i[1]){o.label=i[1],i=a;break}if(i&&o.label<i[2]){o.label=i[2],o.ops.push(a);break}i[2]&&o.ops.pop(),o.trys.pop();continue}a=t.call(e,o)}catch(e){a=[6,e],n=0}finally{r=i=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}"function"==typeof SuppressedError&&SuppressedError;var s,a={};
1
+ "use strict";var t=require("@googleapis/classroom"),e=require("crypto"),r=require("google-auth-library");function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var i=n(e),o=function(){return o=Object.assign||function(t){for(var e,r=1,n=arguments.length;r<n;r++)for(var i in e=arguments[r])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},o.apply(this,arguments)};function s(t,e,r,n){return new(r||(r=Promise))(function(i,o){function s(t){try{c(n.next(t))}catch(t){o(t)}}function a(t){try{c(n.throw(t))}catch(t){o(t)}}function c(t){var e;t.done?i(t.value):(e=t.value,e instanceof r?e:new r(function(t){t(e)})).then(s,a)}c((n=n.apply(t,e||[])).next())})}function a(t,e){var r,n,i,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]},s=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return s.next=a(0),s.throw=a(1),s.return=a(2),"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(c){return function(a){if(r)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(r=1,n&&(i=2&a[0]?n.return:a[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,a[1])).done)return i;switch(n=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,n=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=o.trys,(i=i.length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]<i[3])){o.label=a[1];break}if(6===a[0]&&o.label<i[1]){o.label=i[1],i=a;break}if(i&&o.label<i[2]){o.label=i[2],o.ops.push(a);break}i[2]&&o.ops.pop(),o.trys.pop();continue}a=e.call(t,o)}catch(t){a=[6,t],n=0}finally{r=i=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}"function"==typeof SuppressedError&&SuppressedError;var c,u={};
2
2
  /*!
3
3
  * cookie
4
4
  * Copyright(c) 2012-2014 Roman Shtylman
5
5
  * Copyright(c) 2015 Douglas Christopher Wilson
6
6
  * MIT Licensed
7
- */!function(){if(s)return a;s=1,a.parse=function(e,r){if("string"!=typeof e)throw new TypeError("argument str must be a string");var n={},i=e.length;if(i<2)return n;var o=r&&r.decode||u,s=0,a=0,f=0;do{if(-1===(a=e.indexOf("=",s)))break;if(-1===(f=e.indexOf(";",s)))f=i;else if(a>f){s=e.lastIndexOf(";",a-1)+1;continue}var d=c(e,s,a),p=l(e,a,d),w=e.slice(d,p);if(!t.call(n,w)){var y=c(e,a+1,f),g=l(e,f,y);34===e.charCodeAt(y)&&34===e.charCodeAt(g-1)&&(y++,g--);var m=e.slice(y,g);n[w]=h(m,o)}s=f+1}while(s<i);return n},a.serialize=function(t,s,a){var c=a&&a.encode||encodeURIComponent;if("function"!=typeof c)throw new TypeError("option encode is invalid");if(!r.test(t))throw new TypeError("argument name is invalid");var l=c(s);if(!n.test(l))throw new TypeError("argument val is invalid");var u=t+"="+l;if(!a)return u;if(null!=a.maxAge){var h=Math.floor(a.maxAge);if(!isFinite(h))throw new TypeError("option maxAge is invalid");u+="; Max-Age="+h}if(a.domain){if(!i.test(a.domain))throw new TypeError("option domain is invalid");u+="; Domain="+a.domain}if(a.path){if(!o.test(a.path))throw new TypeError("option path is invalid");u+="; Path="+a.path}if(a.expires){var f=a.expires;if(!function(t){return"[object Date]"===e.call(t)}(f)||isNaN(f.valueOf()))throw new TypeError("option expires is invalid");u+="; Expires="+f.toUTCString()}a.httpOnly&&(u+="; HttpOnly");a.secure&&(u+="; Secure");a.partitioned&&(u+="; Partitioned");if(a.priority){switch("string"==typeof a.priority?a.priority.toLowerCase():a.priority){case"low":u+="; Priority=Low";break;case"medium":u+="; Priority=Medium";break;case"high":u+="; Priority=High";break;default:throw new TypeError("option priority is invalid")}}if(a.sameSite){switch("string"==typeof a.sameSite?a.sameSite.toLowerCase():a.sameSite){case!0:u+="; SameSite=Strict";break;case"lax":u+="; SameSite=Lax";break;case"strict":u+="; SameSite=Strict";break;case"none":u+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}}return u};var e=Object.prototype.toString,t=Object.prototype.hasOwnProperty,r=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,n=/^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/,i=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,o=/^[\u0020-\u003A\u003D-\u007E]*$/;function c(e,t,r){do{var n=e.charCodeAt(t);if(32!==n&&9!==n)return t}while(++t<r);return r}function l(e,t,r){for(;t>r;){var n=e.charCodeAt(--t);if(32!==n&&9!==n)return t+1}return r}function u(e){return-1!==e.indexOf("%")?decodeURIComponent(e):e}function h(e,t){try{return t(e)}catch(t){return e}}}();var c={},l=Array.from({length:64});for(let e=0,t="A".charCodeAt(0),r="Z".charCodeAt(0);e+t<=r;e++){const r=String.fromCharCode(e+t);c[r]=e,l[e]=r}for(let e=0,t="a".charCodeAt(0),r="z".charCodeAt(0);e+t<=r;e++){const r=String.fromCharCode(e+t),n=e+26;c[r]=n,l[n]=r}for(let e=0;e<10;e++){c[e.toString(10)]=e+52;const t=e.toString(10),r=e+52;c[t]=r,l[r]=t}c["-"]=62,l[62]="-",c._=63,l[63]="_";var u=e=>(new TextEncoder).encode(e),h=e=>{const t=e+"=".repeat((4-e.length%4)%4);let r=t.length/4*3;t.endsWith("==")?r-=2:t.endsWith("=")&&r--;const n=new ArrayBuffer(r),i=new DataView(n);for(let e=0;e<t.length;e+=4){let r=0,n=0;for(let i=e,o=e+3;i<=o;i++)if("="===t[i])r>>=6;else{if(!(t[i]in c))throw new TypeError(`Invalid character ${t[i]} in base64 string.`);r|=c[t[i]]<<6*(o-i),n+=6}const o=e/4*3;r>>=n%8;const s=Math.floor(n/8);for(let e=0;e<s;e++){const t=8*(s-e-1);i.setUint8(o+e,(r&255<<t)>>t)}}return new Uint8Array(n)},f=e=>{const t="string"==typeof e?u(e):e;let r="";for(let e=0;e<t.length;e+=3){let n=0,i=0;for(let r=e,o=Math.min(e+3,t.length);r<o;r++)n|=t[r]<<8*(o-r-1),i+=8;const o=Math.ceil(i/6);n<<=6*o-i;for(let e=1;e<=o;e++){const t=6*(o-e);r+=l[(n&63<<t)>>t]}}return r},d={encryption:{saltBits:256,algorithm:"aes-256-cbc",iterations:1,minPasswordlength:32},integrity:{saltBits:256,algorithm:"sha256",iterations:1,minPasswordlength:32},ttl:0,timestampSkewSec:60,localtimeOffsetMsec:0},p=e=>({...e,encryption:{...e.encryption},integrity:{...e.integrity}}),w={"aes-128-ctr":{keyBits:128,ivBits:128,name:"AES-CTR"},"aes-256-cbc":{keyBits:256,ivBits:128,name:"AES-CBC"},sha256:{keyBits:256,name:"SHA-256"}},y="Fe26.2",g=(e,t)=>{if(t<1)throw new Error("Invalid random bits count");return((e,t)=>{const r=new Uint8Array(t);return e.getRandomValues(r),r})(e,Math.ceil(t/8))},m=async(e,t,r)=>{var n;if(!(null==t?void 0:t.length))throw new Error("Empty password");if(null==r||"object"!=typeof r)throw new Error("Bad options");if(!(r.algorithm in w))throw new Error(`Unknown algorithm: ${r.algorithm}`);const i=w[r.algorithm],o={},s=null!=(n=r.hmac)&&n,a=s?{name:"HMAC",hash:i.name}:{name:i.name},c=s?["sign","verify"]:["encrypt","decrypt"];if("string"==typeof t){if(t.length<r.minPasswordlength)throw new Error(`Password string too short (min ${r.minPasswordlength} characters required)`);let{salt:n=""}=r;if(!n){const{saltBits:t=0}=r;if(!t)throw new Error("Missing salt and saltBits options");const i=g(e,t);n=[...new Uint8Array(i)].map(e=>e.toString(16).padStart(2,"0")).join("")}const s=await(async(e,t,r,n,i,o)=>{const s=u(t),a=await e.subtle.importKey("raw",s,{name:"PBKDF2"},!1,["deriveBits"]),c={name:"PBKDF2",hash:o,salt:u(r),iterations:n};return await e.subtle.deriveBits(c,a,8*i)})(e,t,n,r.iterations,i.keyBits/8,"SHA-1"),l=await e.subtle.importKey("raw",s,a,!1,c);o.key=l,o.salt=n}else{if(t.length<i.keyBits/8)throw new Error("Key buffer (password) too small");o.key=await e.subtle.importKey("raw",t,a,!1,c),o.salt=""}return r.iv?o.iv=r.iv:"ivBits"in i&&(o.iv=g(e,i.ivBits)),o},v=(e,t,r)=>["aes-128-ctr"===e?{name:"AES-CTR",counter:t.iv,length:128}:{name:"AES-CBC",iv:t.iv},t.key,"string"==typeof r?u(r):r],E=async(e,t,r,n)=>{const i=await m(e,t,r),o=await e.subtle.decrypt(...v(r.algorithm,i,n));return s=new Uint8Array(o),(new TextDecoder).decode(s);var s},S=async(e,t,r,n)=>{const i=await m(e,t,{...r,hmac:!0}),o=u(n),s=await e.subtle.sign({name:"HMAC"},i.key,o);return{digest:f(new Uint8Array(s)),salt:i.salt}},C=e=>"string"==typeof e||e instanceof Uint8Array?{encryption:e,integrity:e}:"secret"in e?{id:e.id,encryption:e.secret,integrity:e.secret}:{id:e.id,encryption:e.encryption,integrity:e.integrity},b=async(e,t,r,n)=>{if(!r)throw new Error("Empty password");const i=p(n),o=Date.now()+(i.localtimeOffsetMsec||0),s=JSON.stringify(t),a=C(r),{id:c="",encryption:l,integrity:u}=a;if(c&&!/^\w+$/.test(c))throw new Error("Invalid password id");const{encrypted:h,key:d}=await(async(e,t,r,n)=>{const i=await m(e,t,r),o=await e.subtle.encrypt(...v(r.algorithm,i,n));return{encrypted:new Uint8Array(o),key:i}})(e,l,i.encryption,s),w=f(new Uint8Array(h)),g=f(d.iv),E=i.ttl?o+i.ttl:"",b=`${y}*${c}*${d.salt}*${g}*${w}*${E}`,A=await S(e,u,i.integrity,b);return`${b}*${A.salt}*${A.digest}`};const A=globalThis.crypto,k=A.subtle,T=()=>A.randomUUID(),_=e=>A.getRandomValues(e),O={randomUUID:T,getRandomValues:_,subtle:k};var U=Object.freeze({__proto__:null,default:O,getRandomValues:_,randomUUID:T,subtle:k});function I(e){return"string"==typeof e?{1:e}:e}var x,N=function(e){return async function(t,{password:r,ttl:n=1209600}){const i=I(r),o=Math.max(...Object.keys(i).map(Number)),s={id:o.toString(),secret:i[o]};return`${await b(e,t,s,{...d,ttl:1e3*n})}~2`}}(U),R=function(e){return async function(t,{password:r,ttl:n=1209600}){const i=I(r),{sealWithoutVersion:o,tokenVersion:s}=function(e){const[t,r]=e.split("~");return{sealWithoutVersion:t,tokenVersion:null==r?null:parseInt(r,10)}}(t);try{const t=await(async(e,t,r,n)=>{if(!r)throw new Error("Empty password");const i=p(n),o=Date.now()+(i.localtimeOffsetMsec||0),s=t.split("*");if(8!==s.length)throw new Error("Incorrect number of sealed components");const a=s[0];let c=s[1];const l=s[2],u=s[3],f=s[4],d=s[5],w=s[6],g=s[7],m=`${a}*${c}*${l}*${u}*${f}*${d}`;if(y!==a)throw new Error("Wrong mac prefix");if(d){if(!/^\d+$/.test(d))throw new Error("Invalid expiration");if(Number.parseInt(d,10)<=o-1e3*i.timestampSkewSec)throw new Error("Expired seal")}let v="";if(c=c||"default","string"==typeof r||r instanceof Uint8Array)v=r;else{if(!(c in r))throw new Error(`Cannot find password: ${c}`);v=r[c]}v=C(v);const b=i.integrity;if(b.salt=w,!((e,t)=>{let r=e.length===t.length?0:1;r&&(t=e);for(let n=0;n<e.length;n+=1)r|=e.charCodeAt(n)^t.charCodeAt(n);return 0===r})((await S(e,v.integrity,b,m)).digest,g))throw new Error("Bad hmac value");const A=h(f),k=i.encryption;k.salt=l,k.iv=h(u);const T=await E(e,v.encryption,k,A);return T?JSON.parse(T):null})(e,o,i,{...d,ttl:1e3*n})??{};return 2===s?t:{...t.persistent}}catch(e){if(e instanceof Error&&/^(Expired seal|Bad hmac value|Cannot find password|Incorrect number of sealed components)/.test(e.message))return{};throw e}}}(U),B=function(){function e(e){this.encryptionSecret=e,this.ENCRYPTION_SECRET=e}return e.prototype.encryptString=function(t){var r=n.default.randomBytes(e.SALT_BYTES).toString("hex"),i=n.default.randomBytes(e.IV_LENGTH),o=n.default.scryptSync(this.ENCRYPTION_SECRET,r,e.ENCRYPTION_KEY_LENGTH),s=n.default.createCipheriv(e.ALGORITHM,o,i),a=s.update(t,"utf8","hex");return a+=s.final("hex"),"".concat(i.toString("hex"),":").concat(a,":").concat(r)},e.prototype.decryptString=function(t){var r=function(e,t){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var n,i,o=r.call(e),s=[];try{for(;(void 0===t||t-- >0)&&!(n=o.next()).done;)s.push(n.value)}catch(e){i={error:e}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(i)throw i.error}}return s}(t.split(":"),3),i=r[0],o=r[1],s=r[2];if(!i||!o||!s)throw new Error("Invalid encrypted string");var a=Buffer.from(i,"hex"),c=n.default.scryptSync(this.ENCRYPTION_SECRET,s,e.ENCRYPTION_KEY_LENGTH),l=n.default.createDecipheriv(e.ALGORITHM,c,a),u=l.update(o,"hex","utf8");return u+=l.final("utf8")},e.ALGORITHM="aes-256-cbc",e.IV_LENGTH=16,e.SALT_BYTES=16,e.ENCRYPTION_KEY_LENGTH=32,e}();!function(e){e.CONNECTED_USERS_CREDENTIALS="connectedUsersCredentials"}(x||(x={}));var P=function(){function e(e){this.firestore=e,this._firestore=e}return e.prototype.getConnectedUserCredentials=function(e){return i(this,void 0,void 0,function(){var t;return o(this,function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),[4,this._firestore.collection(x.CONNECTED_USERS_CREDENTIALS).doc(e).get()];case 1:return[2,r.sent()];case 2:throw t=r.sent(),console.error(t),new Error("Failed to save users credentials");case 3:return[2]}})})},e.prototype.upsertConnectedUserCredentials=function(e){return i(this,void 0,void 0,function(){var t;return o(this,function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),this._firestore.settings({ignoreUndefinedProperties:!0}),[4,this._firestore.collection(x.CONNECTED_USERS_CREDENTIALS).doc(e.loginHint).set(e)];case 1:return r.sent(),[3,3];case 2:throw t=r.sent(),console.error(t),new Error("Failed to upsert users credentials");case 3:return[2]}})})},e}(),$=function(){function e(e,r,n,s,a){var c=this;if(this.googleClientId=e,this.googleClientSecret=r,this.callbackUrl=n,this.accessToken=s,this.refreshToken=a,!e)throw new Error("Google Client ID is missing");if(!r)throw new Error("Google Client Secret is missing");if(!n)throw new Error("Google OAuth Callback URL is missing");var l=new t.OAuth2Client({clientId:e,clientSecret:r,redirectUri:n,forceRefreshOnFailure:!1});"true"===process.env.GOOGLE_CLASSROOM_DEV_MODE&&s&&(l.refreshHandler=function(){return i(c,void 0,void 0,function(){return o(this,function(e){return[2,{access_token:s,expiry_date:(new Date).getTime()+36e5}]})})}),(s||a)&&l.setCredentials({access_token:s,refresh_token:a}),this.client=l,this.clientId=e}return e.prototype.getAuthenticateUrl=function(e,t){void 0===t&&(t=!1);try{return this.client.generateAuthUrl({access_type:"offline",include_granted_scopes:!0,scope:["https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/classroom.courses.readonly","https://www.googleapis.com/auth/classroom.addons.student","https://www.googleapis.com/auth/classroom.addons.teacher"],loginHint:e,subscribeToNewsletter:t})}catch(e){return console.error(e),null}},e.prototype.exchangeCodeForTokens=function(e){return i(this,void 0,void 0,function(){var t,r,n,i;return o(this,function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,this.client.getToken(e)];case 1:return t=o.sent().tokens,[4,this.client.verifyIdToken({idToken:t.id_token,audience:this.clientId})];case 2:if(r=o.sent(),n=r.getPayload(),!t.access_token)throw new Error("Access token is missing");if(!(null==n?void 0:n.sub))throw new Error("User sub is missing");return[2,{accessToken:t.access_token,loginHint:n.sub,refreshToken:t.refresh_token,profilePictureUrl:null==n?void 0:n.picture,email:n.email}];case 3:return i=o.sent(),console.error(i),[2,null];case 4:return[2]}})})},e.prototype.refreshAccessToken=function(e){return i(this,void 0,void 0,function(){var t,r;return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),this.client.setCredentials({refresh_token:e}),[4,this.client.getAccessToken()];case 1:if(!(t=n.sent()).token)throw new Error("Unable to refresh access token");return[2,t.token];case 2:return r=n.sent(),console.error(r),[2,null];case 3:return[2]}})})},e.prototype.isAuthenticated=function(e){return i(this,void 0,void 0,function(){var t,r;return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,this.client.getTokenInfo(e)];case 1:return t=n.sent(),t.expiry_date<Date.now()?[2,!0]:[2,!1];case 2:return r=n.sent(),console.error(r),[2,!1];case 3:return[2]}})})},e}(),D=function(){function e(e,t,r,n,i,o){this.encryptionSecret=e,this.firestore=t,this.googleOAuthClientId=r,this.googleOAuthClientSecret=n,this.googleOAuthCallbackApiRoute=i,this.sessionSecret=o,this.encryptionService=new B(e),this.firestoreClient=new P(t),this._googleOAuthClientId=r,this._googleOAuthClientSecret=n,this._googleOAuthCallbackApiRoute=i,this._sessionSecret=o}return e.prototype.getOAuthClient=function(e,t){return new $(this._googleOAuthClientId,this._googleOAuthClientSecret,this._googleOAuthCallbackApiRoute,e,t)},e.prototype.getGoogleSignInUrl=function(e){return i(this,arguments,void 0,function(e,t){var r,n;return void 0===t&&(t=!1),o(this,function(i){if(r=this.getOAuthClient(),!(n=r.getAuthenticateUrl(e,t)))throw new Error("Failed to get Google Authentication URL");return[2,n]})})},e.prototype.handleGoogleSignInCallback=function(e,t){return i(this,void 0,void 0,function(){var r,n,i,s;return o(this,function(o){switch(o.label){case 0:return[4,this.getOAuthClient().exchangeCodeForTokens(e)];case 1:if(!(r=o.sent()))throw new Error("Failed to authenticate Google sign-in");return n=r.refreshToken?this.encryptionService.encryptString(r.refreshToken):void 0,i=r.profilePictureUrl?this.encryptionService.encryptString(r.profilePictureUrl):void 0,[4,this.firestoreClient.upsertConnectedUserCredentials({refreshToken:n,profilePictureUrl:i,loginHint:r.loginHint})];case 2:return o.sent(),[4,N({loginHint:r.loginHint,accessToken:r.accessToken},{password:this._sessionSecret})];case 3:return s=o.sent(),t&&r.email?[4,t(r.email)]:[3,5];case 4:o.sent(),o.label=5;case 5:return[2,{encryptedSession:s,profilePictureUrl:r.profilePictureUrl}]}})})},e.prototype.verifyAuthSession=function(e){return i(this,void 0,void 0,function(){var t,r,n,i;return o(this,function(o){switch(o.label){case 0:return[4,R(e,{password:this._sessionSecret})];case 1:return(null==(t=o.sent())?void 0:t.accessToken)&&(null==t?void 0:t.loginHint)?[4,this.firestoreClient.getConnectedUserCredentials(t.loginHint)]:[2,null];case 2:return(r=o.sent())?[4,(n=this.getOAuthClient(t.accessToken,r.refreshToken)).isAuthenticated(t.accessToken)]:[2,null];case 3:return o.sent()?[2,e]:[4,n.refreshAccessToken(r.refreshToken)];case 4:return(i=o.sent())?[4,N({loginHint:t.loginHint,accessToken:i},{password:this._sessionSecret})]:[3,6];case 5:return[2,o.sent()];case 6:return[2,null]}})})},e}();exports.OakGoogleClassroomAddOn=D;
7
+ */!function(){if(c)return u;c=1,u.parse=function(t,r){if("string"!=typeof t)throw new TypeError("argument str must be a string");var n={},i=t.length;if(i<2)return n;var o=r&&r.decode||l,c=0,u=0,d=0;do{if(-1===(u=t.indexOf("=",c)))break;if(-1===(d=t.indexOf(";",c)))d=i;else if(u>d){c=t.lastIndexOf(";",u-1)+1;continue}var f=s(t,c,u),p=a(t,u,f),w=t.slice(f,p);if(!e.call(n,w)){var g=s(t,u+1,d),y=a(t,d,g);34===t.charCodeAt(g)&&34===t.charCodeAt(y-1)&&(g++,y--);var m=t.slice(g,y);n[w]=h(m,o)}c=d+1}while(c<i);return n},u.serialize=function(e,s,a){var c=a&&a.encode||encodeURIComponent;if("function"!=typeof c)throw new TypeError("option encode is invalid");if(!r.test(e))throw new TypeError("argument name is invalid");var u=c(s);if(!n.test(u))throw new TypeError("argument val is invalid");var l=e+"="+u;if(!a)return l;if(null!=a.maxAge){var h=Math.floor(a.maxAge);if(!isFinite(h))throw new TypeError("option maxAge is invalid");l+="; Max-Age="+h}if(a.domain){if(!i.test(a.domain))throw new TypeError("option domain is invalid");l+="; Domain="+a.domain}if(a.path){if(!o.test(a.path))throw new TypeError("option path is invalid");l+="; Path="+a.path}if(a.expires){var d=a.expires;if(!function(e){return"[object Date]"===t.call(e)}(d)||isNaN(d.valueOf()))throw new TypeError("option expires is invalid");l+="; Expires="+d.toUTCString()}a.httpOnly&&(l+="; HttpOnly");a.secure&&(l+="; Secure");a.partitioned&&(l+="; Partitioned");if(a.priority){switch("string"==typeof a.priority?a.priority.toLowerCase():a.priority){case"low":l+="; Priority=Low";break;case"medium":l+="; Priority=Medium";break;case"high":l+="; Priority=High";break;default:throw new TypeError("option priority is invalid")}}if(a.sameSite){switch("string"==typeof a.sameSite?a.sameSite.toLowerCase():a.sameSite){case!0:l+="; SameSite=Strict";break;case"lax":l+="; SameSite=Lax";break;case"strict":l+="; SameSite=Strict";break;case"none":l+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}}return l};var t=Object.prototype.toString,e=Object.prototype.hasOwnProperty,r=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,n=/^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/,i=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,o=/^[\u0020-\u003A\u003D-\u007E]*$/;function s(t,e,r){do{var n=t.charCodeAt(e);if(32!==n&&9!==n)return e}while(++e<r);return r}function a(t,e,r){for(;e>r;){var n=t.charCodeAt(--e);if(32!==n&&9!==n)return e+1}return r}function l(t){return-1!==t.indexOf("%")?decodeURIComponent(t):t}function h(t,e){try{return e(t)}catch(e){return t}}}();var l={},h=Array.from({length:64});for(let t=0,e="A".charCodeAt(0),r="Z".charCodeAt(0);t+e<=r;t++){const r=String.fromCharCode(t+e);l[r]=t,h[t]=r}for(let t=0,e="a".charCodeAt(0),r="z".charCodeAt(0);t+e<=r;t++){const r=String.fromCharCode(t+e),n=t+26;l[r]=n,h[n]=r}for(let t=0;t<10;t++){l[t.toString(10)]=t+52;const e=t.toString(10),r=t+52;l[e]=r,h[r]=e}l["-"]=62,h[62]="-",l._=63,h[63]="_";var d=t=>(new TextEncoder).encode(t),f=t=>{const e=t+"=".repeat((4-t.length%4)%4);let r=e.length/4*3;e.endsWith("==")?r-=2:e.endsWith("=")&&r--;const n=new ArrayBuffer(r),i=new DataView(n);for(let t=0;t<e.length;t+=4){let r=0,n=0;for(let i=t,o=t+3;i<=o;i++)if("="===e[i])r>>=6;else{if(!(e[i]in l))throw new TypeError(`Invalid character ${e[i]} in base64 string.`);r|=l[e[i]]<<6*(o-i),n+=6}const o=t/4*3;r>>=n%8;const s=Math.floor(n/8);for(let t=0;t<s;t++){const e=8*(s-t-1);i.setUint8(o+t,(r&255<<e)>>e)}}return new Uint8Array(n)},p=t=>{const e="string"==typeof t?d(t):t;let r="";for(let t=0;t<e.length;t+=3){let n=0,i=0;for(let r=t,o=Math.min(t+3,e.length);r<o;r++)n|=e[r]<<8*(o-r-1),i+=8;const o=Math.ceil(i/6);n<<=6*o-i;for(let t=1;t<=o;t++){const e=6*(o-t);r+=h[(n&63<<e)>>e]}}return r},w={encryption:{saltBits:256,algorithm:"aes-256-cbc",iterations:1,minPasswordlength:32},integrity:{saltBits:256,algorithm:"sha256",iterations:1,minPasswordlength:32},ttl:0,timestampSkewSec:60,localtimeOffsetMsec:0},g=t=>({...t,encryption:{...t.encryption},integrity:{...t.integrity}}),y={"aes-128-ctr":{keyBits:128,ivBits:128,name:"AES-CTR"},"aes-256-cbc":{keyBits:256,ivBits:128,name:"AES-CBC"},sha256:{keyBits:256,name:"SHA-256"}},m="Fe26.2",v=(t,e)=>{if(e<1)throw new Error("Invalid random bits count");return((t,e)=>{const r=new Uint8Array(e);return t.getRandomValues(r),r})(t,Math.ceil(e/8))},S=async(t,e,r)=>{var n;if(!(null==e?void 0:e.length))throw new Error("Empty password");if(null==r||"object"!=typeof r)throw new Error("Bad options");if(!(r.algorithm in y))throw new Error(`Unknown algorithm: ${r.algorithm}`);const i=y[r.algorithm],o={},s=null!=(n=r.hmac)&&n,a=s?{name:"HMAC",hash:i.name}:{name:i.name},c=s?["sign","verify"]:["encrypt","decrypt"];if("string"==typeof e){if(e.length<r.minPasswordlength)throw new Error(`Password string too short (min ${r.minPasswordlength} characters required)`);let{salt:n=""}=r;if(!n){const{saltBits:e=0}=r;if(!e)throw new Error("Missing salt and saltBits options");const i=v(t,e);n=[...new Uint8Array(i)].map(t=>t.toString(16).padStart(2,"0")).join("")}const s=await(async(t,e,r,n,i,o)=>{const s=d(e),a=await t.subtle.importKey("raw",s,{name:"PBKDF2"},!1,["deriveBits"]),c={name:"PBKDF2",hash:o,salt:d(r),iterations:n};return await t.subtle.deriveBits(c,a,8*i)})(t,e,n,r.iterations,i.keyBits/8,"SHA-1"),u=await t.subtle.importKey("raw",s,a,!1,c);o.key=u,o.salt=n}else{if(e.length<i.keyBits/8)throw new Error("Key buffer (password) too small");o.key=await t.subtle.importKey("raw",e,a,!1,c),o.salt=""}return r.iv?o.iv=r.iv:"ivBits"in i&&(o.iv=v(t,i.ivBits)),o},C=(t,e,r)=>["aes-128-ctr"===t?{name:"AES-CTR",counter:e.iv,length:128}:{name:"AES-CBC",iv:e.iv},e.key,"string"==typeof r?d(r):r],E=async(t,e,r,n)=>{const i=await S(t,e,r),o=await t.subtle.decrypt(...C(r.algorithm,i,n));return s=new Uint8Array(o),(new TextDecoder).decode(s);var s},A=async(t,e,r,n)=>{const i=await S(t,e,{...r,hmac:!0}),o=d(n),s=await t.subtle.sign({name:"HMAC"},i.key,o);return{digest:p(new Uint8Array(s)),salt:i.salt}},b=t=>"string"==typeof t||t instanceof Uint8Array?{encryption:t,integrity:t}:"secret"in t?{id:t.id,encryption:t.secret,integrity:t.secret}:{id:t.id,encryption:t.encryption,integrity:t.integrity},k=async(t,e,r,n)=>{if(!r)throw new Error("Empty password");const i=g(n),o=Date.now()+(i.localtimeOffsetMsec||0),s=JSON.stringify(e),a=b(r),{id:c="",encryption:u,integrity:l}=a;if(c&&!/^\w+$/.test(c))throw new Error("Invalid password id");const{encrypted:h,key:d}=await(async(t,e,r,n)=>{const i=await S(t,e,r),o=await t.subtle.encrypt(...C(r.algorithm,i,n));return{encrypted:new Uint8Array(o),key:i}})(t,u,i.encryption,s),f=p(new Uint8Array(h)),w=p(d.iv),y=i.ttl?o+i.ttl:"",v=`${m}*${c}*${d.salt}*${w}*${f}*${y}`,E=await A(t,l,i.integrity,v);return`${v}*${E.salt}*${E.digest}`};const T=globalThis.crypto,O=T.subtle,I=()=>T.randomUUID(),_=t=>T.getRandomValues(t),U={randomUUID:I,getRandomValues:_,subtle:O};var R=Object.freeze({__proto__:null,default:U,getRandomValues:_,randomUUID:I,subtle:O});function x(t){return"string"==typeof t?{1:t}:t}var N,P=function(t){return async function(e,{password:r,ttl:n=1209600}){const i=x(r),o=Math.max(...Object.keys(i).map(Number)),s={id:o.toString(),secret:i[o]};return`${await k(t,e,s,{...w,ttl:1e3*n})}~2`}}(R),B=function(t){return async function(e,{password:r,ttl:n=1209600}){const i=x(r),{sealWithoutVersion:o,tokenVersion:s}=function(t){const[e,r]=t.split("~");return{sealWithoutVersion:e,tokenVersion:null==r?null:parseInt(r,10)}}(e);try{const e=await(async(t,e,r,n)=>{if(!r)throw new Error("Empty password");const i=g(n),o=Date.now()+(i.localtimeOffsetMsec||0),s=e.split("*");if(8!==s.length)throw new Error("Incorrect number of sealed components");const a=s[0];let c=s[1];const u=s[2],l=s[3],h=s[4],d=s[5],p=s[6],w=s[7],y=`${a}*${c}*${u}*${l}*${h}*${d}`;if(m!==a)throw new Error("Wrong mac prefix");if(d){if(!/^\d+$/.test(d))throw new Error("Invalid expiration");if(Number.parseInt(d,10)<=o-1e3*i.timestampSkewSec)throw new Error("Expired seal")}let v="";if(c=c||"default","string"==typeof r||r instanceof Uint8Array)v=r;else{if(!(c in r))throw new Error(`Cannot find password: ${c}`);v=r[c]}v=b(v);const S=i.integrity;if(S.salt=p,!((t,e)=>{let r=t.length===e.length?0:1;r&&(e=t);for(let n=0;n<t.length;n+=1)r|=t.charCodeAt(n)^e.charCodeAt(n);return 0===r})((await A(t,v.integrity,S,y)).digest,w))throw new Error("Bad hmac value");const C=f(h),k=i.encryption;k.salt=u,k.iv=f(l);const T=await E(t,v.encryption,k,C);return T?JSON.parse(T):null})(t,o,i,{...w,ttl:1e3*n})??{};return 2===s?e:{...e.persistent}}catch(t){if(t instanceof Error&&/^(Expired seal|Bad hmac value|Cannot find password|Incorrect number of sealed components)/.test(t.message))return{};throw t}}}(R),H=function(){function e(t,e){this.baseUrl=t,this.oAuthClient=e,this.baseUrl=t,this.oAuthClient=e}return e.prototype.getClassroomClient=function(){return s(this,void 0,void 0,function(){var e;return a(this,function(r){switch(r.label){case 0:return[4,this.oAuthClient.getOAuth2Client()];case 1:return e=r.sent(),[2,new t.classroom_v1.Classroom({auth:e})]}})})},e.prototype.createAnnouncementAttachment=function(t){return s(this,void 0,void 0,function(){var e,r,n,i,s,c,u,l,h,d,f,p;return a(this,function(a){switch(a.label){case 0:return e=t.courseId,r=t.itemId,n=t.addOnToken,i=t.title,s=t.lessonSlug,c=t.programeSlug,u=t.unitSlug,l=t.maxPoints,[4,this.getClassroomClient()];case 1:return h=a.sent(),d=l?{maxPoints:l,studentWorkReviewUri:{uri:"".concat(this.baseUrl,"/pupils/programmes/").concat(c,"/units/").concat(u,"/lessons/").concat(s)}}:{},[4,h.courses.courseWork.addOnAttachments.create({courseId:e,itemId:r,addOnToken:n,requestBody:o({title:i,teacherViewUri:{uri:"".concat(this.baseUrl,"/pupils/programmes/").concat(c,"/units/").concat(u,"/lessons/").concat(s)},studentViewUri:{uri:"".concat(this.baseUrl,"/pupils/programmes/").concat(c,"/units/").concat(u,"/lessons/").concat(s)}},d)})];case 2:return f=a.sent(),p=f.data.maxPoints?{maxPoints:f.data.maxPoints,studentWorkReviewUri:f.data.studentWorkReviewUri}:{},[2,o({courseId:f.data.courseId,postId:f.data.postId,id:f.data.id,title:f.data.title,teacherViewUri:f.data.teacherViewUri,studentViewUri:f.data.studentViewUri,itemId:f.data.itemId},p)]}})})},e.prototype.submitPupilResponse=function(t){return s(this,void 0,void 0,function(){return a(this,function(e){switch(e.label){case 0:return[4,this.getClassroomClient()];case 1:return[4,e.sent().courses.courseWork.addOnAttachments.studentSubmissions.patch({courseId:t.courseId,itemId:t.itemId,attachmentId:t.attachmentId,submissionId:t.submissionId,updateMask:"pointsEarned",requestBody:{pointsEarned:t.pointsEarned}})];case 2:return[2,e.sent().data]}})})},e.prototype.fetchPupilResponse=function(t){return s(this,void 0,void 0,function(){return a(this,function(e){switch(e.label){case 0:return[4,this.getClassroomClient()];case 1:return[4,e.sent().courses.courseWork.addOnAttachments.studentSubmissions.get({courseId:t.courseId,itemId:t.itemId,attachmentId:t.attachmentId,submissionId:t.submissionId})];case 2:return[2,e.sent().data]}})})},e}(),D=function(){function t(t){this.encryptionSecret=t,this.ENCRYPTION_SECRET=t}return t.prototype.encryptString=function(e){var r=i.default.randomBytes(t.SALT_BYTES).toString("hex"),n=i.default.randomBytes(t.IV_LENGTH),o=i.default.scryptSync(this.ENCRYPTION_SECRET,r,t.ENCRYPTION_KEY_LENGTH),s=i.default.createCipheriv(t.ALGORITHM,o,n),a=s.update(e,"utf8","hex");return a+=s.final("hex"),"".concat(n.toString("hex"),":").concat(a,":").concat(r)},t.prototype.decryptString=function(e){var r=function(t,e){var r="function"==typeof Symbol&&t[Symbol.iterator];if(!r)return t;var n,i,o=r.call(t),s=[];try{for(;(void 0===e||e-- >0)&&!(n=o.next()).done;)s.push(n.value)}catch(t){i={error:t}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(i)throw i.error}}return s}(e.split(":"),3),n=r[0],o=r[1],s=r[2];if(!n||!o||!s)throw new Error("Invalid encrypted string");var a=Buffer.from(n,"hex"),c=i.default.scryptSync(this.ENCRYPTION_SECRET,s,t.ENCRYPTION_KEY_LENGTH),u=i.default.createDecipheriv(t.ALGORITHM,c,a),l=u.update(o,"hex","utf8");return l+=u.final("utf8")},t.ALGORITHM="aes-256-cbc",t.IV_LENGTH=16,t.SALT_BYTES=16,t.ENCRYPTION_KEY_LENGTH=32,t}();!function(t){t.CONNECTED_USERS_CREDENTIALS="connectedUsersCredentials",t.CLASSROOM_ATTACHMENTS="classroomAttachments"}(N||(N={}));var L=function(){function t(t){this.firestore=t,this._firestore=t}return t.prototype.getConnectedUserCredentials=function(t){return s(this,void 0,void 0,function(){var e;return a(this,function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),[4,this._firestore.collection(N.CONNECTED_USERS_CREDENTIALS).doc(t).get()];case 1:return[2,r.sent()];case 2:throw e=r.sent(),console.error(e),new Error("Failed to save users credentials");case 3:return[2]}})})},t.prototype.upsertConnectedUserCredentials=function(t){return s(this,void 0,void 0,function(){var e;return a(this,function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),this._firestore.settings({ignoreUndefinedProperties:!0}),[4,this._firestore.collection(N.CONNECTED_USERS_CREDENTIALS).doc(t.loginHint).set(t)];case 1:return r.sent(),[3,3];case 2:throw e=r.sent(),console.error(e),new Error("Failed to upsert users credentials");case 3:return[2]}})})},t.prototype.upsertClassroomAttachment=function(t){return s(this,void 0,void 0,function(){var e;return a(this,function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),[4,this._firestore.collection(N.CLASSROOM_ATTACHMENTS).doc(t.attachmentId).set(t)];case 1:return r.sent(),[3,3];case 2:throw e=r.sent(),console.error(e),new Error("Failed to upsert classroom attachment");case 3:return[2]}})})},t.prototype.getClassroomAttachmentById=function(t){return s(this,void 0,void 0,function(){var e,r;return a(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,this._firestore.collection(N.CLASSROOM_ATTACHMENTS).doc(t).get()];case 1:return(e=n.sent()).exists?[2,e.data()]:[2,null];case 2:throw r=n.sent(),console.error(r),new Error("Failed to get classroom attachment by ID");case 3:return[2]}})})},t}(),M=function(){function t(t,e,n,i,o){var c=this;if(this.googleClientId=t,this.googleClientSecret=e,this.callbackUrl=n,this.accessToken=i,this.refreshToken=o,!t)throw new Error("Google Client ID is missing");if(!e)throw new Error("Google Client Secret is missing");if(!n)throw new Error("Google OAuth Callback URL is missing");var u=new r.OAuth2Client({clientId:t,clientSecret:e,redirectUri:n,forceRefreshOnFailure:!1});"true"===process.env.GOOGLE_CLASSROOM_DEV_MODE&&i&&(u.refreshHandler=function(){return s(c,void 0,void 0,function(){return a(this,function(t){return[2,{access_token:i,expiry_date:(new Date).getTime()+36e5}]})})}),(i||o)&&u.setCredentials({access_token:i,refresh_token:o}),this.client=u,this.clientId=t}return t.prototype.getAuthenticateUrl=function(t,e){void 0===e&&(e=!1);try{return this.client.generateAuthUrl({access_type:"offline",include_granted_scopes:!0,scope:["https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/classroom.courses.readonly","https://www.googleapis.com/auth/classroom.addons.student","https://www.googleapis.com/auth/classroom.addons.teacher"],loginHint:t,subscribeToNewsletter:e})}catch(t){return console.error(t),null}},t.prototype.exchangeCodeForTokens=function(t){return s(this,void 0,void 0,function(){var e,r,n,i;return a(this,function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,this.client.getToken(t)];case 1:return e=o.sent().tokens,[4,this.client.verifyIdToken({idToken:e.id_token,audience:this.clientId})];case 2:if(r=o.sent(),n=r.getPayload(),!e.access_token)throw new Error("Access token is missing");if(!(null==n?void 0:n.sub))throw new Error("User sub is missing");return[2,{accessToken:e.access_token,loginHint:n.sub,refreshToken:e.refresh_token,profilePictureUrl:null==n?void 0:n.picture,email:n.email}];case 3:return i=o.sent(),console.error(i),[2,null];case 4:return[2]}})})},t.prototype.refreshAccessToken=function(t){return s(this,void 0,void 0,function(){var e,r;return a(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),this.client.setCredentials({refresh_token:t}),[4,this.client.getAccessToken()];case 1:if(!(e=n.sent()).token)throw new Error("Unable to refresh access token");return[2,e.token];case 2:return r=n.sent(),console.error(r),[2,null];case 3:return[2]}})})},t.prototype.isAuthenticated=function(t){return s(this,void 0,void 0,function(){var e,r;return a(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,this.client.getTokenInfo(t)];case 1:return e=n.sent(),e.expiry_date<Date.now()?[2,!1]:[2,!0];case 2:return r=n.sent(),console.error(r),[2,!1];case 3:return[2]}})})},t.prototype.getOAuth2Client=function(){return s(this,void 0,void 0,function(){return a(this,function(t){return[2,this.client]})})},t}(),$=function(){function t(t,e,r,n,i,o,s){this.encryptionSecret=t,this.firestore=e,this.googleOAuthClientId=r,this.googleOAuthClientSecret=n,this.googleOAuthCallbackApiRoute=i,this.sessionSecret=o,this.baseUrl=s,this.encryptionService=new D(t),this.firestoreClient=new L(e),this._googleOAuthClientId=r,this._googleOAuthClientSecret=n,this._googleOAuthCallbackApiRoute=i,this._sessionSecret=o}return t.prototype.getOAuthClient=function(t,e){return new M(this._googleOAuthClientId,this._googleOAuthClientSecret,this._googleOAuthCallbackApiRoute,t,e)},t.prototype.getGoogleSignInUrl=function(t){return s(this,arguments,void 0,function(t,e){var r,n;return void 0===e&&(e=!1),a(this,function(i){if(r=this.getOAuthClient(),!(n=r.getAuthenticateUrl(t,e)))throw new Error("Failed to get Google Authentication URL");return[2,n]})})},t.prototype.handleGoogleSignInCallback=function(t,e){return s(this,void 0,void 0,function(){var r,n,i,o,s;return a(this,function(a){switch(a.label){case 0:return[4,this.getOAuthClient().exchangeCodeForTokens(t)];case 1:if(!(r=a.sent()))throw new Error("Failed to authenticate Google sign-in");return n=r.accessToken,i=r.refreshToken?this.encryptionService.encryptString(r.refreshToken):void 0,o=r.profilePictureUrl?this.encryptionService.encryptString(r.profilePictureUrl):void 0,[4,P({loginHint:r.loginHint,accessToken:n},{password:this._sessionSecret})];case 2:return s=a.sent(),[4,this.firestoreClient.upsertConnectedUserCredentials({refreshToken:i,profilePictureUrl:o,loginHint:r.loginHint})];case 3:return a.sent(),e&&r.email?[4,e(r.email)]:[3,5];case 4:a.sent(),a.label=5;case 5:return[2,{encryptedSession:s,accessToken:n,profilePictureUrl:r.profilePictureUrl}]}})})},t.prototype.decryptSession=function(t){return s(this,void 0,void 0,function(){var e;return a(this,function(r){switch(r.label){case 0:return[4,B(t,{password:this._sessionSecret})];case 1:return(null==(e=r.sent())?void 0:e.accessToken)&&(null==e?void 0:e.loginHint)?[2,e]:[2,null]}})})},t.prototype.getSessionAndUser=function(t){return s(this,void 0,void 0,function(){var e,r,n;return a(this,function(i){switch(i.label){case 0:return[4,this.decryptSession(t)];case 1:return(e=i.sent())?[4,this.firestoreClient.getConnectedUserCredentials(e.loginHint)]:[2,null];case 2:return(r=i.sent())?(n=r.refreshToken?this.encryptionService.decryptString(r.refreshToken):void 0,r.refreshToken=n,process.env.GOOGLE_CLASSROOM_DEV_REFRESH_TOKEN&&(r.refreshToken=process.env.GOOGLE_CLASSROOM_DEV_REFRESH_TOKEN),[2,{session:e,user:r}]):[2,null]}})})},t.prototype.verifyAuthSession=function(t,e){return s(this,void 0,void 0,function(){var r,n,i,o;return a(this,function(s){switch(s.label){case 0:return t&&e?[4,this.getSessionAndUser(t)]:[2,null];case 1:return(r=s.sent())&&e&&(null===(o=null==r?void 0:r.session)||void 0===o?void 0:o.accessToken)===e?[4,(n=this.getOAuthClient(e,r.user.refreshToken)).isAuthenticated(e)]:[2,null];case 2:return s.sent()?[2,{session:t,token:e}]:[4,n.refreshAccessToken(r.user.refreshToken)];case 3:return(i=s.sent())?[4,P({loginHint:r.session.loginHint,accessToken:i},{password:this._sessionSecret})]:[3,5];case 4:return[2,{session:s.sent(),token:i}];case 5:return[2,null]}})})},t.prototype.createAttachment=function(t,e,r){return s(this,void 0,void 0,function(){var n,i,s,c;return a(this,function(a){switch(a.label){case 0:return[4,this.getSessionAndUser(r)];case 1:if(!(n=a.sent())||e!==n.session.accessToken)throw new Error("Invalid Google Classroom session");return i=this.getOAuthClient(e,n.user.refreshToken),[4,new H(this.baseUrl,i).createAnnouncementAttachment(t)];case 2:return s=a.sent(),c=o(o({},s),{attachmentId:s.id||"",createdAt:(new Date).toISOString()}),[4,this.firestoreClient.upsertClassroomAttachment(c)];case 3:return a.sent(),[4,this.firestoreClient.getClassroomAttachmentById(s.id)];case 4:return[2,a.sent()]}})})},t}();exports.OakGoogleClassroomAddOn=$;
8
8
  //# sourceMappingURL=index.js.map