diff --git a/composer.json b/composer.json index 42c538bf..4cbd5f75 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,7 @@ "illuminate/events": "^11.23.0", "illuminate/queue": "^11.23.0", "illuminate/support": "^11.23.0", + "laravel/prompts": "^0.1", "nesbot/carbon": "^2.70", "spatie/laravel-data": "^4.11", "spatie/laravel-query-builder": "^5.5", diff --git a/config/cachet.php b/config/cachet.php index b79e4b3f..455cb5da 100644 --- a/config/cachet.php +++ b/config/cachet.php @@ -107,4 +107,14 @@ | */ 'docker' => env('CACHET_DOCKER', false), + + /* + |-------------------------------------------------------------------------- + | Cachet Database Connection + |-------------------------------------------------------------------------- + | + | Support using an alternative database connection, defaults to default connecton of application + | + */ + 'database_connection' => env('CACHET_DB_CONNECTION', config('database.default')), ]; diff --git a/database/migrations/2024_01_22_205110_create_default_settings.php b/database/migrations/2024_01_22_205110_create_default_settings.php index 8acd874d..b0e5c8f1 100644 --- a/database/migrations/2024_01_22_205110_create_default_settings.php +++ b/database/migrations/2024_01_22_205110_create_default_settings.php @@ -14,7 +14,15 @@ public function up(): void rescue(fn () => $this->migrator->add('app.install_id', Str::random(40))); rescue(fn () => $this->migrator->add('app.name', 'Cachet')); rescue(fn () => $this->migrator->add('app.domain')); - rescue(fn () => $this->migrator->add('app.about')); + rescue(fn () => $this->migrator->add('app.about', <<<'ABOUT' + Cachet is a **beautiful** and **powerful** open-source status page system. + + To access the [dashboard](/dashboard), use the following credentials: + - `test@test.com` + - `test123` + + Please [consider sponsoring](https://github.com/cachethq/cachet?sponsor=1) the continued development of Cachet. + ABOUT)); rescue(fn () => $this->migrator->add('app.timezone', 'UTC')); rescue(fn () => $this->migrator->add('app.locale', 'en')); rescue(fn () => $this->migrator->add('app.incident_days', 7)); diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index ce5bc83f..a01aab28 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -31,33 +31,24 @@ class DatabaseSeeder extends Seeder */ public function run(): void { - DB::table('users')->truncate(); - DB::table('incidents')->truncate(); - DB::table('components')->truncate(); - DB::table('component_groups')->truncate(); - DB::table('schedules')->truncate(); - DB::table('metrics')->truncate(); - DB::table('metric_points')->truncate(); - DB::table('updates')->truncate(); - /** @var \Illuminate\Foundation\Auth\User $userModel */ $userModel = config('cachet.user_model'); - $user = $userModel::create([ + $user = $userModel::query()->firstOrCreate([ 'name' => 'Cachet Demo', 'email' => 'test@test.com', 'password' => bcrypt('test123'), 'email_verified_at' => now(), ]); - Schedule::create([ + Schedule::query()->firstOrCreate([ 'name' => 'Documentation Maintenance', 'message' => 'We will be conducting maintenance on our documentation servers. Documentation may not be available during this time.', 'scheduled_at' => now()->subHours(12)->subMinutes(45), 'completed_at' => now()->subHours(12), ]); - tap(Schedule::create([ + tap(Schedule::query()->firstOrCreate([ 'name' => 'Documentation Maintenance', 'message' => 'We will be conducting maintenance on our documentation servers. You may experience degraded performance during this time.', 'scheduled_at' => now()->addHours(24), @@ -76,7 +67,7 @@ public function run(): void $schedule->updates()->save($update); }); - $componentGroup = ComponentGroup::create([ + $componentGroup = ComponentGroup::query()->firstOrCreate([ 'name' => 'Cachet', 'collapsed' => ComponentGroupVisibilityEnum::expanded, 'visible' => ResourceVisibilityEnum::guest, @@ -104,14 +95,14 @@ public function run(): void ], ]); - Component::create([ + Component::query()->firstOrCreate([ 'name' => 'Laravel Artisan Cheatsheet', 'description' => 'The Laravel Artisan Cheatsheet.', 'link' => 'https://artisan.page', 'status' => ComponentStatusEnum::operational, ]); - $metric = Metric::create([ + $metric = Metric::query()->firstOrCreate([ 'name' => 'Cachet API Requests', 'suffix' => 'req/s', 'description' => 'The number of requests to the Cachet API.', @@ -127,7 +118,7 @@ public function run(): void 'created_at' => now()->subMinutes(random_int(0, $i * 60)), ])); - tap(Incident::create([ + tap(Incident::query()->firstOrCreate([ 'name' => 'DNS Provider Outage', 'message' => 'We\'re investigating an issue with our DNS provider causing the site to be offline.', 'status' => IncidentStatusEnum::fixed, @@ -164,7 +155,7 @@ public function run(): void $incident->updates()->save($update); }); - $incident = Incident::create([ + $incident = Incident::query()->firstOrCreate([ 'name' => 'Documentation Performance Degradation', 'message' => 'We\'re investigating an issue with our documentation causing the site to be slow.', 'status' => IncidentStatusEnum::fixed, @@ -191,34 +182,13 @@ public function run(): void $incident->updates()->save($update); - IncidentTemplate::create([ + IncidentTemplate::query()->firstOrCreate([ 'name' => 'Third-Party Service Outage', 'slug' => 'third-party-service-outage', 'template' => 'We\'re investigating an issue with a third-party provider ({{ name }}) causing our services to be offline.', 'engine' => IncidentTemplateEngineEnum::twig, ]); - $appSettings = app(AppSettings::class); - $appSettings->name = 'Cachet v3.x Demo'; - $appSettings->about = <<<'ABOUT' -Cachet is a **beautiful** and **powerful** open-source status page system. - -To access the [dashboard](/dashboard), use the following credentials: -- `test@test.com` -- `test123` - -Please [consider sponsoring](https://github.com/cachethq/cachet?sponsor=1) the continued development of Cachet. -ABOUT; - $appSettings->show_support = true; - $appSettings->timezone = 'UTC'; - $appSettings->show_timezone = false; - $appSettings->only_disrupted_days = false; - $appSettings->incident_days = 7; - $appSettings->refresh_rate = null; - $appSettings->dashboard_login_link = true; - $appSettings->major_outage_threshold = 25; - $appSettings->save(); - $customizationSettings = app(CustomizationSettings::class); $customizationSettings->header = <<<'HTML' diff --git a/public/build/assets/cachet-DCZQ8JcZ.js b/public/build/assets/cachet-DCZQ8JcZ.js deleted file mode 100644 index 8a73d659..00000000 --- a/public/build/assets/cachet-DCZQ8JcZ.js +++ /dev/null @@ -1,18 +0,0 @@ -var ye=!1,xe=!1,rt=[],we=-1;function yr(t){xr(t)}function xr(t){rt.includes(t)||rt.push(t),wr()}function Mi(t){let e=rt.indexOf(t);e!==-1&&e>we&&rt.splice(e,1)}function wr(){!xe&&!ye&&(ye=!0,queueMicrotask($r))}function $r(){ye=!1,xe=!0;for(let t=0;tt.effect(e,{scheduler:i=>{$e?yr(i):i()}}),Li=t.raw}function ui(t){ft=t}function Sr(t){let e=()=>{};return[n=>{let r=ft(n);return t._x_effects||(t._x_effects=new Set,t._x_runEffects=()=>{t._x_effects.forEach(s=>s())}),t._x_effects.add(r),e=()=>{r!==void 0&&(t._x_effects.delete(r),gt(r))},r},()=>{e()}]}function Bi(t,e){let i=!0,n,r=ft(()=>{let s=t();JSON.stringify(s),i?n=s:queueMicrotask(()=>{e(s,n),n=s}),i=!1});return()=>gt(r)}var ji=[],Vi=[],Wi=[];function Tr(t){Wi.push(t)}function Be(t,e){typeof e=="function"?(t._x_cleanups||(t._x_cleanups=[]),t._x_cleanups.push(e)):(e=t,Vi.push(e))}function qi(t){ji.push(t)}function Hi(t,e,i){t._x_attributeCleanups||(t._x_attributeCleanups={}),t._x_attributeCleanups[e]||(t._x_attributeCleanups[e]=[]),t._x_attributeCleanups[e].push(i)}function zi(t,e){t._x_attributeCleanups&&Object.entries(t._x_attributeCleanups).forEach(([i,n])=>{(e===void 0||e.includes(i))&&(n.forEach(r=>r()),delete t._x_attributeCleanups[i])})}function Cr(t){if(t._x_cleanups)for(;t._x_cleanups.length;)t._x_cleanups.pop()()}var je=new MutationObserver(He),Ve=!1;function We(){je.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),Ve=!0}function Ui(){kr(),je.disconnect(),Ve=!1}var xt=[];function kr(){let t=je.takeRecords();xt.push(()=>t.length>0&&He(t));let e=xt.length;queueMicrotask(()=>{if(xt.length===e)for(;xt.length>0;)xt.shift()()})}function k(t){if(!Ve)return t();Ui();let e=t();return We(),e}var qe=!1,Ut=[];function Ir(){qe=!0}function Dr(){qe=!1,He(Ut),Ut=[]}function He(t){if(qe){Ut=Ut.concat(t);return}let e=new Set,i=new Set,n=new Map,r=new Map;for(let s=0;sa.nodeType===1&&e.add(a)),t[s].removedNodes.forEach(a=>a.nodeType===1&&i.add(a))),t[s].type==="attributes")){let a=t[s].target,o=t[s].attributeName,l=t[s].oldValue,u=()=>{n.has(a)||n.set(a,[]),n.get(a).push({name:o,value:a.getAttribute(o)})},c=()=>{r.has(a)||r.set(a,[]),r.get(a).push(o)};a.hasAttribute(o)&&l===null?u():a.hasAttribute(o)?(c(),u()):c()}r.forEach((s,a)=>{zi(a,s)}),n.forEach((s,a)=>{ji.forEach(o=>o(a,s))});for(let s of i)e.has(s)||Vi.forEach(a=>a(s));e.forEach(s=>{s._x_ignoreSelf=!0,s._x_ignore=!0});for(let s of e)i.has(s)||s.isConnected&&(delete s._x_ignoreSelf,delete s._x_ignore,Wi.forEach(a=>a(s)),s._x_ignore=!0,s._x_ignoreSelf=!0);e.forEach(s=>{delete s._x_ignoreSelf,delete s._x_ignore}),e=null,i=null,n=null,r=null}function Gi(t){return Dt(ht(t))}function It(t,e,i){return t._x_dataStack=[e,...ht(i||t)],()=>{t._x_dataStack=t._x_dataStack.filter(n=>n!==e)}}function ht(t){return t._x_dataStack?t._x_dataStack:typeof ShadowRoot=="function"&&t instanceof ShadowRoot?ht(t.host):t.parentNode?ht(t.parentNode):[]}function Dt(t){return new Proxy({objects:t},Nr)}var Nr={ownKeys({objects:t}){return Array.from(new Set(t.flatMap(e=>Object.keys(e))))},has({objects:t},e){return e==Symbol.unscopables?!1:t.some(i=>Object.prototype.hasOwnProperty.call(i,e)||Reflect.has(i,e))},get({objects:t},e,i){return e=="toJSON"?Rr:Reflect.get(t.find(n=>Reflect.has(n,e))||{},e,i)},set({objects:t},e,i,n){const r=t.find(a=>Object.prototype.hasOwnProperty.call(a,e))||t[t.length-1],s=Object.getOwnPropertyDescriptor(r,e);return s!=null&&s.set&&(s!=null&&s.get)?s.set.call(n,i)||!0:Reflect.set(r,e,i)}};function Rr(){return Reflect.ownKeys(this).reduce((e,i)=>(e[i]=Reflect.get(this,i),e),{})}function Qi(t){let e=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,i=(n,r="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([s,{value:a,enumerable:o}])=>{if(o===!1||a===void 0||typeof a=="object"&&a!==null&&a.__v_skip)return;let l=r===""?s:`${r}.${s}`;typeof a=="object"&&a!==null&&a._x_interceptor?n[s]=a.initialize(t,l,s):e(a)&&a!==n&&!(a instanceof Element)&&i(a,l)})};return i(t)}function Ji(t,e=()=>{}){let i={initialValue:void 0,_x_interceptor:!0,initialize(n,r,s){return t(this.initialValue,()=>Pr(n,r),a=>Ee(n,r,a),r,s)}};return e(i),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let r=i.initialize.bind(i);i.initialize=(s,a,o)=>{let l=n.initialize(s,a,o);return i.initialValue=l,r(s,a,o)}}else i.initialValue=n;return i}}function Pr(t,e){return e.split(".").reduce((i,n)=>i[n],t)}function Ee(t,e,i){if(typeof e=="string"&&(e=e.split(".")),e.length===1)t[e[0]]=i;else{if(e.length===0)throw error;return t[e[0]]||(t[e[0]]={}),Ee(t[e[0]],e.slice(1),i)}}var Yi={};function L(t,e){Yi[t]=e}function Oe(t,e){return Object.entries(Yi).forEach(([i,n])=>{let r=null;function s(){if(r)return r;{let[a,o]=rn(e);return r={interceptor:Ji,...a},Be(e,o),r}}Object.defineProperty(t,`$${i}`,{get(){return n(e,s())},enumerable:!1})}),t}function Fr(t,e,i,...n){try{return i(...n)}catch(r){Ct(r,t,e)}}function Ct(t,e,i=void 0){t=Object.assign(t??{message:"No error message given."},{el:e,expression:i}),console.warn(`Alpine Expression Error: ${t.message} - -${i?'Expression: "'+i+`" - -`:""}`,e),setTimeout(()=>{throw t},0)}var qt=!0;function Xi(t){let e=qt;qt=!1;let i=t();return qt=e,i}function st(t,e,i={}){let n;return N(t,e)(r=>n=r,i),n}function N(...t){return Zi(...t)}var Zi=tn;function Ar(t){Zi=t}function tn(t,e){let i={};Oe(i,t);let n=[i,...ht(t)],r=typeof e=="function"?Kr(n,e):Lr(n,e,t);return Fr.bind(null,t,e,r)}function Kr(t,e){return(i=()=>{},{scope:n={},params:r=[]}={})=>{let s=e.apply(Dt([n,...t]),r);Gt(i,s)}}var pe={};function Mr(t,e){if(pe[t])return pe[t];let i=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(t.trim())||/^(let|const)\s/.test(t.trim())?`(async()=>{ ${t} })()`:t,s=(()=>{try{let a=new i(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`);return Object.defineProperty(a,"name",{value:`[Alpine] ${t}`}),a}catch(a){return Ct(a,e,t),Promise.resolve()}})();return pe[t]=s,s}function Lr(t,e,i){let n=Mr(e,i);return(r=()=>{},{scope:s={},params:a=[]}={})=>{n.result=void 0,n.finished=!1;let o=Dt([s,...t]);if(typeof n=="function"){let l=n(n,o).catch(u=>Ct(u,i,e));n.finished?(Gt(r,n.result,o,a,i),n.result=void 0):l.then(u=>{Gt(r,u,o,a,i)}).catch(u=>Ct(u,i,e)).finally(()=>n.result=void 0)}}}function Gt(t,e,i,n,r){if(qt&&typeof e=="function"){let s=e.apply(i,n);s instanceof Promise?s.then(a=>Gt(t,a,i,n)).catch(a=>Ct(a,r,e)):t(s)}else typeof e=="object"&&e instanceof Promise?e.then(s=>t(s)):t(e)}var ze="x-";function mt(t=""){return ze+t}function Br(t){ze=t}var Qt={};function C(t,e){return Qt[t]=e,{before(i){if(!Qt[i]){console.warn(String.raw`Cannot find directive \`${i}\`. \`${t}\` will use the default order of execution`);return}const n=nt.indexOf(i);nt.splice(n>=0?n:nt.indexOf("DEFAULT"),0,t)}}}function jr(t){return Object.keys(Qt).includes(t)}function Ue(t,e,i){if(e=Array.from(e),t._x_virtualDirectives){let s=Object.entries(t._x_virtualDirectives).map(([o,l])=>({name:o,value:l})),a=en(s);s=s.map(o=>a.find(l=>l.name===o.name)?{name:`x-bind:${o.name}`,value:`"${o.value}"`}:o),e=e.concat(s)}let n={};return e.map(on((s,a)=>n[s]=a)).filter(un).map(qr(n,i)).sort(Hr).map(s=>Wr(t,s))}function en(t){return Array.from(t).map(on()).filter(e=>!un(e))}var Se=!1,Ot=new Map,nn=Symbol();function Vr(t){Se=!0;let e=Symbol();nn=e,Ot.set(e,[]);let i=()=>{for(;Ot.get(e).length;)Ot.get(e).shift()();Ot.delete(e)},n=()=>{Se=!1,i()};t(i),n()}function rn(t){let e=[],i=o=>e.push(o),[n,r]=Sr(t);return e.push(r),[{Alpine:Rt,effect:n,cleanup:i,evaluateLater:N.bind(N,t),evaluate:st.bind(st,t)},()=>e.forEach(o=>o())]}function Wr(t,e){let i=()=>{},n=Qt[e.type]||i,[r,s]=rn(t);Hi(t,e.original,s);let a=()=>{t._x_ignore||t._x_ignoreSelf||(n.inline&&n.inline(t,e,r),n=n.bind(n,t,e,r),Se?Ot.get(nn).push(n):n())};return a.runCleanups=s,a}var sn=(t,e)=>({name:i,value:n})=>(i.startsWith(t)&&(i=i.replace(t,e)),{name:i,value:n}),an=t=>t;function on(t=()=>{}){return({name:e,value:i})=>{let{name:n,value:r}=ln.reduce((s,a)=>a(s),{name:e,value:i});return n!==e&&t(n,e),{name:n,value:r}}}var ln=[];function Ge(t){ln.push(t)}function un({name:t}){return cn().test(t)}var cn=()=>new RegExp(`^${ze}([^:^.]+)\\b`);function qr(t,e){return({name:i,value:n})=>{let r=i.match(cn()),s=i.match(/:([a-zA-Z0-9\-_:]+)/),a=i.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],o=e||t[i]||i;return{type:r?r[1]:null,value:s?s[1]:null,modifiers:a.map(l=>l.replace(".","")),expression:n,original:o}}}var Te="DEFAULT",nt=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",Te,"teleport"];function Hr(t,e){let i=nt.indexOf(t.type)===-1?Te:t.type,n=nt.indexOf(e.type)===-1?Te:e.type;return nt.indexOf(i)-nt.indexOf(n)}function St(t,e,i={}){t.dispatchEvent(new CustomEvent(e,{detail:i,bubbles:!0,composed:!0,cancelable:!0}))}function J(t,e){if(typeof ShadowRoot=="function"&&t instanceof ShadowRoot){Array.from(t.children).forEach(r=>J(r,e));return}let i=!1;if(e(t,()=>i=!0),i)return;let n=t.firstElementChild;for(;n;)J(n,e),n=n.nextElementSibling}function P(t,...e){console.warn(`Alpine Warning: ${t}`,...e)}var ci=!1;function zr(){ci&&P("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),ci=!0,document.body||P("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's `